sedna 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/{CHANGES → CHANGES.rdoc} +9 -0
  2. data/{README → README.rdoc} +23 -25
  3. data/Rakefile +32 -9
  4. data/ext/{extconf.rb → sedna/extconf.rb} +33 -21
  5. data/ext/{sedna.c → sedna/sedna.c} +48 -40
  6. data/test/sedna_test.rb +9 -9
  7. data/vendor/sedna/AUTHORS +18 -0
  8. data/vendor/sedna/COPYRIGHT +90 -0
  9. data/vendor/sedna/LICENSE +202 -0
  10. data/vendor/sedna/Makefile.include +423 -0
  11. data/vendor/sedna/Makefile.platform +31 -0
  12. data/vendor/sedna/depend.sed +48 -0
  13. data/vendor/sedna/driver/c/Makefile +98 -0
  14. data/vendor/sedna/driver/c/libsedna.c +1998 -0
  15. data/vendor/sedna/driver/c/libsedna.h +199 -0
  16. data/vendor/sedna/driver/c/sednamt.def +21 -0
  17. data/vendor/sedna/driver/c/sp_defs.h +186 -0
  18. data/vendor/sedna/kernel/common/FastXptrHash.cpp +101 -0
  19. data/vendor/sedna/kernel/common/IntHash.h +314 -0
  20. data/vendor/sedna/kernel/common/IntList.h +224 -0
  21. data/vendor/sedna/kernel/common/Makefile +30 -0
  22. data/vendor/sedna/kernel/common/SSMMsg.cpp +459 -0
  23. data/vendor/sedna/kernel/common/SSMMsg.h +142 -0
  24. data/vendor/sedna/kernel/common/XptrHash.h +435 -0
  25. data/vendor/sedna/kernel/common/argtable.c +972 -0
  26. data/vendor/sedna/kernel/common/argtable.h +896 -0
  27. data/vendor/sedna/kernel/common/base.cpp +339 -0
  28. data/vendor/sedna/kernel/common/base.h +226 -0
  29. data/vendor/sedna/kernel/common/bit_set.cpp +157 -0
  30. data/vendor/sedna/kernel/common/bit_set.h +55 -0
  31. data/vendor/sedna/kernel/common/commutil.h +67 -0
  32. data/vendor/sedna/kernel/common/config.h +62 -0
  33. data/vendor/sedna/kernel/common/counted_ptr.h +74 -0
  34. data/vendor/sedna/kernel/common/errdbg/ErrorCodes.java +1056 -0
  35. data/vendor/sedna/kernel/common/errdbg/Makefile +34 -0
  36. data/vendor/sedna/kernel/common/errdbg/assert.c +133 -0
  37. data/vendor/sedna/kernel/common/errdbg/d_printf.c +150 -0
  38. data/vendor/sedna/kernel/common/errdbg/d_printf.h +91 -0
  39. data/vendor/sedna/kernel/common/errdbg/error.codes +1743 -0
  40. data/vendor/sedna/kernel/common/errdbg/error_codes.c +531 -0
  41. data/vendor/sedna/kernel/common/errdbg/error_codes.h +549 -0
  42. data/vendor/sedna/kernel/common/errdbg/error_codes_scm.scm +527 -0
  43. data/vendor/sedna/kernel/common/errdbg/event_log.c +956 -0
  44. data/vendor/sedna/kernel/common/errdbg/event_log.h +226 -0
  45. data/vendor/sedna/kernel/common/errdbg/exceptions.cpp +155 -0
  46. data/vendor/sedna/kernel/common/errdbg/exceptions.h +559 -0
  47. data/vendor/sedna/kernel/common/errdbg/gen_error_codes +0 -0
  48. data/vendor/sedna/kernel/common/errdbg/gen_error_codes.c +345 -0
  49. data/vendor/sedna/kernel/common/gmm.cpp +192 -0
  50. data/vendor/sedna/kernel/common/gmm.h +29 -0
  51. data/vendor/sedna/kernel/common/ipc_ops.cpp +435 -0
  52. data/vendor/sedna/kernel/common/ipc_ops.h +51 -0
  53. data/vendor/sedna/kernel/common/lfsGlobals.h +12 -0
  54. data/vendor/sedna/kernel/common/lm_base.h +90 -0
  55. data/vendor/sedna/kernel/common/mmgr/Makefile +11 -0
  56. data/vendor/sedna/kernel/common/mmgr/aset.c +1185 -0
  57. data/vendor/sedna/kernel/common/mmgr/mcxt.c +741 -0
  58. data/vendor/sedna/kernel/common/mmgr/memnodes.h +70 -0
  59. data/vendor/sedna/kernel/common/mmgr/memutils.h +145 -0
  60. data/vendor/sedna/kernel/common/mmgr/se_alloc.h +321 -0
  61. data/vendor/sedna/kernel/common/mmgr/track.c +214 -0
  62. data/vendor/sedna/kernel/common/pping.cpp +672 -0
  63. data/vendor/sedna/kernel/common/pping.h +119 -0
  64. data/vendor/sedna/kernel/common/rcv_test.cpp +273 -0
  65. data/vendor/sedna/kernel/common/rcv_test.h +19 -0
  66. data/vendor/sedna/kernel/common/sedna.c +128 -0
  67. data/vendor/sedna/kernel/common/sedna.h +49 -0
  68. data/vendor/sedna/kernel/common/sedna_ef.h +52 -0
  69. data/vendor/sedna/kernel/common/sm_vmm_data.h +144 -0
  70. data/vendor/sedna/kernel/common/sp.c +93 -0
  71. data/vendor/sedna/kernel/common/sp.h +36 -0
  72. data/vendor/sedna/kernel/common/st/Makefile +20 -0
  73. data/vendor/sedna/kernel/common/st/os_linux/stacktrace.c +213 -0
  74. data/vendor/sedna/kernel/common/st/os_nt/stacktrace.c +338 -0
  75. data/vendor/sedna/kernel/common/st/os_other/stacktrace.c +39 -0
  76. data/vendor/sedna/kernel/common/st/stacktrace.h +72 -0
  77. data/vendor/sedna/kernel/common/st/stacktrfmt.c +64 -0
  78. data/vendor/sedna/kernel/common/tr_debug.cpp +112 -0
  79. data/vendor/sedna/kernel/common/tr_debug.h +22 -0
  80. data/vendor/sedna/kernel/common/u/Makefile +14 -0
  81. data/vendor/sedna/kernel/common/u/u.c +268 -0
  82. data/vendor/sedna/kernel/common/u/u.h +715 -0
  83. data/vendor/sedna/kernel/common/u/uatomic.h +12 -0
  84. data/vendor/sedna/kernel/common/u/udl.h +31 -0
  85. data/vendor/sedna/kernel/common/u/uevent.c +406 -0
  86. data/vendor/sedna/kernel/common/u/uevent.h +71 -0
  87. data/vendor/sedna/kernel/common/u/ugnames.cpp +330 -0
  88. data/vendor/sedna/kernel/common/u/ugnames.h +134 -0
  89. data/vendor/sedna/kernel/common/u/uhash_map.h +77 -0
  90. data/vendor/sedna/kernel/common/u/uhdd.c +1018 -0
  91. data/vendor/sedna/kernel/common/u/uhdd.h +206 -0
  92. data/vendor/sedna/kernel/common/u/ummap.cpp +268 -0
  93. data/vendor/sedna/kernel/common/u/ummap.h +60 -0
  94. data/vendor/sedna/kernel/common/u/umutex.c +145 -0
  95. data/vendor/sedna/kernel/common/u/umutex.h +65 -0
  96. data/vendor/sedna/kernel/common/u/upipe.cpp +244 -0
  97. data/vendor/sedna/kernel/common/u/upipe.h +74 -0
  98. data/vendor/sedna/kernel/common/u/uprocess.c +767 -0
  99. data/vendor/sedna/kernel/common/u/uprocess.h +91 -0
  100. data/vendor/sedna/kernel/common/u/usafesync.h +41 -0
  101. data/vendor/sedna/kernel/common/u/usecurity.c +150 -0
  102. data/vendor/sedna/kernel/common/u/usecurity.h +55 -0
  103. data/vendor/sedna/kernel/common/u/usem.c +891 -0
  104. data/vendor/sedna/kernel/common/u/usem.h +83 -0
  105. data/vendor/sedna/kernel/common/u/ushm.c +222 -0
  106. data/vendor/sedna/kernel/common/u/ushm.h +46 -0
  107. data/vendor/sedna/kernel/common/u/usocket.c +541 -0
  108. data/vendor/sedna/kernel/common/u/usocket.h +118 -0
  109. data/vendor/sedna/kernel/common/u/usystem.c +57 -0
  110. data/vendor/sedna/kernel/common/u/usystem.h +46 -0
  111. data/vendor/sedna/kernel/common/u/uthread.c +259 -0
  112. data/vendor/sedna/kernel/common/u/uthread.h +95 -0
  113. data/vendor/sedna/kernel/common/u/utime.c +65 -0
  114. data/vendor/sedna/kernel/common/u/utime.h +40 -0
  115. data/vendor/sedna/kernel/common/u/uutils.c +142 -0
  116. data/vendor/sedna/kernel/common/u/uutils.h +65 -0
  117. data/vendor/sedna/kernel/common/ugc.cpp +156 -0
  118. data/vendor/sedna/kernel/common/ugc.h +15 -0
  119. data/vendor/sedna/kernel/common/utils.cpp +156 -0
  120. data/vendor/sedna/kernel/common/utils.h +133 -0
  121. data/vendor/sedna/kernel/common/version.c +16 -0
  122. data/vendor/sedna/kernel/common/version.h +21 -0
  123. data/vendor/sedna/kernel/common/wustructures.h +18 -0
  124. data/vendor/sedna/kernel/common/wutypes.h +34 -0
  125. data/vendor/sedna/kernel/common/xptr.cpp +17 -0
  126. data/vendor/sedna/kernel/common/xptr.h +211 -0
  127. data/vendor/sedna/ver +1 -0
  128. metadata +142 -14
@@ -0,0 +1,31 @@
1
+
2
+
3
+ OS := $(shell (uname | sed 's/^CYGWIN_NT.*$$/CYGWIN_NT/'))
4
+ ifeq ("$(OS)", "CYGWIN_NT")
5
+
6
+ PLATFORM = WIN32
7
+
8
+ else
9
+
10
+ PLATFORM = UNIX
11
+
12
+
13
+ ifeq ("$(OS)","Linux")
14
+ SUB_PLATFORM = Linux
15
+ else
16
+ ifeq ("$(OS)","Darwin")
17
+ SUB_PLATFORM = Darwin
18
+ else
19
+ ifeq ("$(OS)","SunOS")
20
+ SUB_PLATFORM = SunOS
21
+ else
22
+ ifeq ("$(OS)","FreeBSD")
23
+ SUB_PLATFORM = FreeBSD
24
+ else
25
+ SUB_PLATFORM = Unknown
26
+ endif
27
+ endif
28
+ endif
29
+ endif
30
+
31
+ endif
@@ -0,0 +1,48 @@
1
+ s% string.h\( \|\(\\\|\r\?$\)\)% \2%
2
+ s% string\( \|\(\\\|\r\?$\)\)% \2%
3
+ s% vector\( \|\(\\\|\r\?$\)\)% \2%
4
+ s% list\( \|\(\\\|\r\?$\)\)% \2%
5
+ s% map\( \|\(\\\|\r\?$\)\)% \2%
6
+ s% set\( \|\(\\\|\r\?$\)\)% \2%
7
+ s% fstream\( \|\(\\\|\r\?$\)\)% \2%
8
+ s% iostream\( \|\(\\\|\r\?$\)\)% \2%
9
+ s% ostream\( \|\(\\\|\r\?$\)\)% \2%
10
+ s% ios\( \|\(\\\|\r\?$\)\)% \2%
11
+ s% strstream\( \|\(\\\|\r\?$\)\)% \2%
12
+ s% sstream\( \|\(\\\|\r\?$\)\)% \2%
13
+ s% algorithm\( \|\(\\\|\r\?$\)\)% \2%
14
+ s% functional\( \|\(\\\|\r\?$\)\)% \2%
15
+ s% iterator\( \|\(\\\|\r\?$\)\)% \2%
16
+ s% stdio.h\( \|\(\\\|\r\?$\)\)% \2%
17
+ s% io.h\( \|\(\\\|\r\?$\)\)% \2%
18
+ s% stdlib.h\( \|\(\\\|\r\?$\)\)% \2%
19
+ s% ctype.h\( \|\(\\\|\r\?$\)\)% \2%
20
+ s% errno.h\( \|\(\\\|\r\?$\)\)% \2%
21
+ s% windows.h\( \|\(\\\|\r\?$\)\)% \2%
22
+ s% winsock.h\( \|\(\\\|\r\?$\)\)% \2%
23
+ s% process.h\( \|\(\\\|\r\?$\)\)% \2%
24
+ s% float.h\( \|\(\\\|\r\?$\)\)% \2%
25
+ s% sys/types.h\( \|\(\\\|\r\?$\)\)% \2%
26
+ s% sys/timeb.h\( \|\(\\\|\r\?$\)\)% \2%
27
+ s% sys/stat.h\( \|\(\\\|\r\?$\)\)% \2%
28
+ s% time.h\( \|\(\\\|\r\?$\)\)% \2%
29
+ s% Accctrl.h\( \|\(\\\|\r\?$\)\)% \2%
30
+ s% aclapi.h\( \|\(\\\|\r\?$\)\)% \2%
31
+ s% limits.h\( \|\(\\\|\r\?$\)\)% \2%
32
+ s% stddef.h\( \|\(\\\|\r\?$\)\)% \2%
33
+ s% math.h\( \|\(\\\|\r\?$\)\)% \2%
34
+ s% malloc.h\( \|\(\\\|\r\?$\)\)% \2%
35
+ s% stdarg.h\( \|\(\\\|\r\?$\)\)% \2%
36
+ s% setjmp.h\( \|\(\\\|\r\?$\)\)% \2%
37
+ s% jmp.h\( \|\(\\\|\r\?$\)\)% \2%
38
+ s% unistd.h\( \|\(\\\|\r\?$\)\)% \2%
39
+ s% direct.h\( \|\(\\\|\r\?$\)\)% \2%
40
+ s% crtdbg.h\( \|\(\\\|\r\?$\)\)% \2%
41
+ s% fcntl.h\( \|\(\\\|\r\?$\)\)% \2%
42
+ s% tchar.h\( \|\(\\\|\r\?$\)\)% \2%
43
+ s% signal.h\( \|\(\\\|\r\?$\)\)% \2%
44
+ s% sql.h\( \|\(\\\|\r\?$\)\)% \2%
45
+ s% sqltypes.h\( \|\(\\\|\r\?$\)\)% \2%
46
+ s% sqlext.h\( \|\(\\\|\r\?$\)\)% \2%
47
+ s% ieeefp.h\( \|\(\\\|\r\?$\)\)% \2%
48
+
@@ -0,0 +1,98 @@
1
+ #
2
+ # Makefile for libsedna
3
+ #
4
+
5
+ PP = ../..
6
+
7
+ VPATH = . $(PP)/kernel/common/u $(PP)/kernel/common/errdbg $(PP)/kernel/common
8
+
9
+ include $(PP)/Makefile.include
10
+
11
+ ifeq ("$(PLATFORM)", "WIN32")
12
+ all: libsednamt$(LIB_EXT) libsednamd$(LIB_EXT) sednamt$(DL_EXT)
13
+ @echo ===================================================================
14
+ @echo C Driver Done
15
+ @echo ===================================================================
16
+ else
17
+ all: libsedna$(LIB_EXT)
18
+ @echo ===================================================================
19
+ @echo C Driver Done
20
+ @echo ===================================================================
21
+ endif
22
+
23
+ OBJS = libsedna$(OBJ_EXT) usocket$(OBJ_EXT) uhdd$(OBJ_EXT) sp$(OBJ_EXT) \
24
+ uutils$(OBJ_EXT) usecurity$(OBJ_EXT) d_printf$(OBJ_EXT) \
25
+ error_codes$(OBJ_EXT) u$(OBJ_EXT)
26
+
27
+ ifneq ($(findstring clean, $(MAKECMDGOALS)), clean)
28
+ ifndef NO_DEP
29
+ include $(OBJS:$(OBJ_EXT)=.d)
30
+ endif
31
+ endif
32
+
33
+ MT_OBJS = $(OBJS:$(OBJ_EXT)=.mt$(OBJ_EXT))
34
+ DL_MT_OBJS = $(OBJS:$(OBJ_EXT)=.dl.mt$(OBJ_EXT))
35
+
36
+ error_codes.d: error.codes
37
+ NO_DEP=1; export NO_DEP; $(MAKE) -C $(PP)/kernel/common/errdbg generated
38
+ touch error_codes.d
39
+
40
+
41
+ ifeq ("$(PLATFORM)", "WIN32")
42
+
43
+ # WIN32
44
+ OBJ_NAME = /Fo
45
+ CFLAGS += /DSE_NO_EVENT_LOG
46
+ CFLAGS_DL += /DSE_NO_EVENT_LOG
47
+
48
+ # static multi-threaded library linked with /MT[d]
49
+ libsednamt$(LIB_EXT): $(MT_OBJS)
50
+ $(LB) $(LIBFLAGS) $(LIBOUT)$@ $^
51
+
52
+ # static multi-threaded library linked with /MD[d]
53
+ libsednamd$(LIB_EXT): $(DL_MT_OBJS)
54
+ $(LB) $(LIBFLAGS) $(LIBOUT)$@ $^
55
+
56
+ # dynamic multi-threaded library linked with /MT[d]
57
+ sednamt$(DL_EXT): $(MT_OBJS)
58
+ $(LD) $(LFLAGS_NOLIB) /DLL /DEF:sednamt$(DEF_EXT) $(LIBOUT)$@ $^
59
+ if (test -e $@.manifest); then \
60
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@\;2; \
61
+ $(REMOVE) $@.manifest; \
62
+ else \
63
+ echo "There is no manifest file to embed."; \
64
+ fi
65
+
66
+ %.mt$(OBJ_EXT): %.d
67
+
68
+ %.mt$(OBJ_EXT): %.c
69
+ $(CC) $(CFLAGS) $(OBJ_NAME)$@ $<
70
+
71
+ %.dl.mt$(OBJ_EXT): %.d
72
+
73
+ %.dl.mt$(OBJ_EXT): %.c
74
+ $(CC) $(CFLAGS_DL) $(OBJ_NAME)$@ $<
75
+
76
+ else # UNIX
77
+ LD=gcc # It must be enough to build C-driver!
78
+ OBJ_NAME = -o
79
+ CFLAGS += $(CFLAGS_SL)
80
+
81
+ libsedna$(LIB_EXT): $(MT_OBJS)
82
+ $(LB) $(LIBFLAGS) $(LIBOUT)$@ $^
83
+
84
+ %.mt$(OBJ_EXT): %.d
85
+
86
+ %.mt$(OBJ_EXT): %.c
87
+ $(CC) $(CFLAGS) $(OBJ_NAME) $@ $<
88
+ endif
89
+
90
+
91
+ ################################################################################
92
+ # Clean #
93
+ ################################################################################
94
+ .PHONY: clean
95
+
96
+ clean: generic_clean
97
+ -$(REMOVE) *.exp *$(DL_EXT)
98
+
@@ -0,0 +1,1998 @@
1
+ /*
2
+ * File: libsedna.c
3
+ * Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
4
+ */
5
+
6
+ #include "libsedna.h"
7
+ #include "common/errdbg/error_codes.h"
8
+ #include "common/errdbg/d_printf.h"
9
+ #include "common/sp.h"
10
+ #include "common/u/uutils.h"
11
+ #include "common/u/usocket.h"
12
+ #include "common/u/uhdd.h"
13
+
14
+ #ifdef _MSC_VER
15
+ #pragma comment(lib,"Advapi32.lib")
16
+ #pragma comment(lib,"WS2_32.lib")
17
+ #endif
18
+
19
+ /******************************************************************************
20
+ * Internal Driver Functions
21
+ *****************************************************************************/
22
+
23
+ static void setServerErrorMsg(struct SednaConnection *conn, struct msg_struct msg)
24
+ {
25
+ int length;
26
+ if (msg.length <= 0) return;
27
+ net_int2int(&(conn->last_error), msg.body);
28
+ net_int2int(&length, msg.body + 5);
29
+ if (length <= 0) return;
30
+ memcpy(conn->last_error_msg, msg.body + 9, length);
31
+ conn->last_error_msg[length] = '\0';
32
+ }
33
+
34
+ static void setDriverErrorMsg(struct SednaConnection *conn, int error_code, const char* details)
35
+ {
36
+ conn->last_error = error_code;
37
+ strcpy(conn->last_error_msg, "SEDNA Message: ERROR ");
38
+ strcat(conn->last_error_msg, user_error_code_entries[conn->last_error].code);
39
+ strcat(conn->last_error_msg, "\n");
40
+ strcat(conn->last_error_msg, user_error_code_entries[conn->last_error].descr);
41
+ if (details != NULL)
42
+ {
43
+ strcat(conn->last_error_msg, "\nDetails: ");
44
+ strcat(conn->last_error_msg, details);
45
+ }
46
+ }
47
+
48
+ static void clearLastError(struct SednaConnection *conn)
49
+ {
50
+ conn->last_error = SEDNA_OPERATION_SUCCEEDED;
51
+ }
52
+
53
+ static void release(struct SednaConnection *conn)
54
+ {
55
+ ushutdown_close_socket(conn->socket, NULL);
56
+ uSocketCleanup(NULL);
57
+ }
58
+
59
+ static void connectionFailure(struct SednaConnection *conn, int error_code, const char* details, struct msg_struct* msg)
60
+ {
61
+ if (msg != NULL)
62
+ setServerErrorMsg(conn, *msg);
63
+ else
64
+ setDriverErrorMsg(conn, error_code, details);
65
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
66
+ conn->isConnectionOk = SEDNA_CONNECTION_FAILED;
67
+ }
68
+
69
+ /* returns 1 if the document is currently loading [into the collection], 0 otherwise */
70
+ static char isBulkLoadStarted(struct SednaConnection *conn)
71
+ {
72
+ return conn->cbl.bulk_load_started;
73
+ }
74
+ /* returns 1 if this document is currently loading [into this collection], 0 otherwise */
75
+ static char isBulkLoadOf(struct SednaConnection *conn, const char* doc_name, const char* col_name)
76
+ {
77
+ if ((conn->cbl.bulk_load_started) && (strcmp(conn->cbl.doc_name, doc_name) == 0))
78
+ {
79
+ if (col_name)
80
+ {
81
+ if(0 == strcmp(conn->cbl.col_name, col_name)) return 1;
82
+ else return 0;
83
+ }
84
+ else
85
+ return 1;
86
+ }
87
+ return 0;
88
+ }
89
+
90
+ /* sets bulk load of the document [into the collection] is started */
91
+ static void setBulkLoadStarted(struct SednaConnection *conn, const char* doc_name, const char* col_name)
92
+ {
93
+ conn->cbl.bulk_load_started = 1;
94
+ strcpy(conn->cbl.doc_name, doc_name);
95
+ if (col_name)
96
+ strcpy(conn->cbl.col_name, col_name);
97
+ }
98
+
99
+ /* sets bulk load of the document [into the collection] is finished */
100
+ static void setBulkLoadFinished(struct SednaConnection *conn)
101
+ {
102
+ conn->cbl.bulk_load_started = 0;
103
+ strcpy(conn->cbl.doc_name, "");
104
+ strcpy(conn->cbl.col_name, "");
105
+ }
106
+
107
+ static int begin_handler(struct SednaConnection *conn)
108
+ {
109
+ /* send 210 - BeginTransaction*/
110
+ conn->msg.instruction = se_BeginTransaction;
111
+ conn->msg.length = 0;
112
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
113
+ {
114
+ connectionFailure(conn, SE3006, "Connection was broken while trying to begin transaction", NULL);
115
+ return SEDNA_ERROR;
116
+ }
117
+
118
+ /* read 100 or 230 - BeginTransactionOk or 240 - BeginTransactionFailed*/
119
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
120
+ {
121
+ connectionFailure(conn, SE3007, "Connection was broken while trying to begin transaction", NULL);
122
+ return SEDNA_ERROR;
123
+ }
124
+
125
+ if (conn->msg.instruction == se_ErrorResponse)
126
+ {
127
+ setServerErrorMsg(conn, conn->msg);
128
+ return SEDNA_BEGIN_TRANSACTION_FAILED;
129
+ }
130
+ else if (conn->msg.instruction == se_BeginTransactionFailed) /* BeginTransactionFailed */
131
+ {
132
+ setServerErrorMsg(conn, conn->msg);
133
+ return SEDNA_BEGIN_TRANSACTION_FAILED;
134
+ }
135
+ else if (conn->msg.instruction == se_BeginTransactionOk) /* BeginTransactionOk */
136
+ {
137
+ conn->in_query = 0;
138
+ conn->isInTransaction = SEDNA_TRANSACTION_ACTIVE;
139
+ return SEDNA_BEGIN_TRANSACTION_SUCCEEDED;
140
+ }
141
+ else
142
+ {
143
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
144
+ return SEDNA_BEGIN_TRANSACTION_FAILED;
145
+ }
146
+ }
147
+
148
+ static int commit_handler(struct SednaConnection *conn)
149
+ {
150
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
151
+
152
+ /* send 220 - CommitTransaction*/
153
+ conn->msg.instruction = se_CommitTransaction;
154
+ conn->msg.length = 0;
155
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
156
+ {
157
+ connectionFailure(conn, SE3006, "Connection was broken while trying to commit transaction", NULL);
158
+ return SEDNA_ERROR;
159
+ }
160
+
161
+ /* read 100 or 250 - CommitTransactionOk or 260 - CommitTransactionFailed*/
162
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
163
+ {
164
+ connectionFailure(conn, SE3007, "Connection was broken while trying to commit transaction", NULL);
165
+ return SEDNA_ERROR;
166
+ }
167
+
168
+ if (conn->msg.instruction == se_ErrorResponse)
169
+ {
170
+ setServerErrorMsg(conn, conn->msg);
171
+ return SEDNA_COMMIT_TRANSACTION_FAILED;
172
+ }
173
+ else if (conn->msg.instruction == se_CommitTransactionFailed) /* CommitTransactionFailed */
174
+ {
175
+ setServerErrorMsg(conn, conn->msg);
176
+ return SEDNA_COMMIT_TRANSACTION_FAILED;
177
+ }
178
+ else if (conn->msg.instruction == se_CommitTransactionOk) /* CommitTransactionOk */
179
+ {
180
+ return SEDNA_COMMIT_TRANSACTION_SUCCEEDED;
181
+ }
182
+ else
183
+ {
184
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
185
+ return SEDNA_COMMIT_TRANSACTION_FAILED;
186
+ }
187
+ }
188
+
189
+ static int rollback_handler(struct SednaConnection *conn)
190
+ {
191
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
192
+
193
+ /* send 225 - RollbackTransaction*/
194
+ conn->msg.instruction = se_RollbackTransaction;
195
+ conn->msg.length = 0;
196
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
197
+ {
198
+ connectionFailure(conn, SE3006, "Connection was broken while trying to rollback transaction", NULL);
199
+ return SEDNA_ERROR;
200
+ }
201
+
202
+ /* read 100 or 255 - RollbackTransactionOk or 265 - RollbackTransactionFailed*/
203
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
204
+ {
205
+ connectionFailure(conn, SE3007, "Connection was broken while trying to rollback transaction", NULL);
206
+ return SEDNA_ERROR;
207
+ }
208
+
209
+ if (conn->msg.instruction == se_ErrorResponse)
210
+ {
211
+ setServerErrorMsg(conn, conn->msg);
212
+ return SEDNA_ROLLBACK_TRANSACTION_FAILED;
213
+ }
214
+ else if (conn->msg.instruction == se_RollbackTransactionFailed) /* RollbackTransactionFailed */
215
+ {
216
+ setServerErrorMsg(conn, conn->msg);
217
+ return SEDNA_ROLLBACK_TRANSACTION_FAILED;
218
+ }
219
+ else if (conn->msg.instruction == se_RollbackTransactionOk) /* RollbackTransactionOk */
220
+ {
221
+ conn->in_query = 0;
222
+ return SEDNA_ROLLBACK_TRANSACTION_SUCCEEDED;
223
+ }
224
+ else
225
+ {
226
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
227
+ return SEDNA_ROLLBACK_TRANSACTION_FAILED;
228
+ }
229
+ }
230
+
231
+ /*return 1 - clean ok*/
232
+ /*error - SEDNA_ERROR*/
233
+ static int cleanSocket(struct SednaConnection *conn)
234
+ {
235
+ conn->local_data_length = 0;
236
+ conn->local_data_offset = 0;
237
+ if (!conn->socket_keeps_data)
238
+ return 0;
239
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
240
+ {
241
+ connectionFailure(conn, SE3007, "Connection was broken while application result retrival", NULL);
242
+ return SEDNA_ERROR;
243
+ }
244
+
245
+ while ((conn->msg.instruction != se_ItemEnd) && (conn->msg.instruction != se_ResultEnd))
246
+ {
247
+ if (conn->msg.instruction == se_ErrorResponse)
248
+ {
249
+ connectionFailure(conn, 0, NULL, &(conn->msg));
250
+ return SEDNA_ERROR;
251
+ }
252
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
253
+ {
254
+ connectionFailure(conn, SE3007, "Connection was broken while application result retrival", NULL);
255
+ return SEDNA_ERROR;
256
+ }
257
+ }
258
+ if (conn->autocommit)
259
+ {
260
+ int comm_res = commit_handler(conn);
261
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
262
+ return SEDNA_ERROR;
263
+ }
264
+
265
+ conn->socket_keeps_data = 0;
266
+ if (conn->msg.instruction == se_ResultEnd)
267
+ conn->result_end = 1;
268
+
269
+ return 1;
270
+ }
271
+
272
+ /* Takes the data from server when execute a query
273
+ * and decide if the query failed or succeeded
274
+ */
275
+ static int resultQueryHandler(struct SednaConnection *conn)
276
+ {
277
+ int _type_offset = 0;
278
+ int url_length = 0;
279
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
280
+ {
281
+ connectionFailure(conn, SE3007, "Connection was broken while executing statement", NULL);
282
+ return SEDNA_ERROR;
283
+ }
284
+ while (conn->msg.instruction == se_DebugInfo)
285
+ {
286
+ if (conn->debug_handler)
287
+ {
288
+ int length;
289
+ int debug_type;
290
+ char debug_info[SE_SOCKET_MSG_BUF_SIZE+1];
291
+ if (conn->msg.length <= 0)
292
+ {
293
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
294
+ return SEDNA_ERROR;
295
+ }
296
+ net_int2int(&debug_type, conn->msg.body);
297
+ net_int2int(&length, conn->msg.body + 5);
298
+ if (length <= 0)
299
+ {
300
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
301
+ return SEDNA_ERROR;
302
+ }
303
+ memcpy(debug_info, conn->msg.body + 9, length);
304
+ debug_info[length] = '\0';
305
+ conn->debug_handler(debug_type, debug_info);
306
+ }
307
+
308
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
309
+ {
310
+ connectionFailure(conn, SE3007, "Connection was broken while executing statement", NULL);
311
+ return SEDNA_ERROR;
312
+ }
313
+ }
314
+ if (conn->msg.instruction == se_ErrorResponse)
315
+ {
316
+ setServerErrorMsg(conn, conn->msg);
317
+ conn->socket_keeps_data = 0; /*set the flag - Socket keeps item data*/
318
+ conn->result_end = 1; /*set the flag - there are items*/
319
+ conn->in_query = 0;
320
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
321
+ return SEDNA_QUERY_FAILED;
322
+ }
323
+ else if (conn->msg.instruction == se_ItemPart || conn->msg.instruction == se_ItemStart) /* ItemPart */
324
+ {
325
+ if(conn->msg.instruction == se_ItemStart)
326
+ {
327
+ if (conn->msg.body[2])
328
+ {
329
+ /* If URI is presented (protocol 4 and higher) then just skip it
330
+ * 3 stands for se_ItemStart header,
331
+ * 1 stands for string type (0 in current implementation
332
+ * 4 stands for url string length
333
+ */
334
+ net_int2int(&url_length, conn->msg.body + 3 + 1);
335
+ _type_offset = 3 + 1 + 4 + url_length;
336
+
337
+ }
338
+ else
339
+ {
340
+ _type_offset = 3;
341
+ }
342
+ }
343
+ memcpy(conn->local_data_buf, conn->msg.body + 5 + _type_offset, conn->msg.length - 5 - _type_offset);
344
+ conn->local_data_length = conn->msg.length - 5 - _type_offset;
345
+ conn->local_data_offset = 0;
346
+ conn->socket_keeps_data = 1; /* set the flag - Socket keeps item data */
347
+ conn->result_end = 0; /* set the flag - there are items */
348
+ conn->in_query = 1;
349
+
350
+ return SEDNA_QUERY_SUCCEEDED;
351
+ }
352
+ else if (conn->msg.instruction == se_ItemEnd) /* ItemEnd */
353
+ {
354
+ conn->local_data_length = 0;
355
+ conn->local_data_offset = 0;
356
+ conn->socket_keeps_data = 0; /* set the flag - Socket does not keep item data */
357
+ conn->result_end = 0; /* set the flag - there are items */
358
+ conn->in_query = 1;
359
+ return SEDNA_QUERY_SUCCEEDED;
360
+ }
361
+ else if (conn->msg.instruction == se_ResultEnd) /* ResultEnd */
362
+ {
363
+ conn->local_data_length = 0;
364
+ conn->local_data_offset = 0;
365
+ conn->socket_keeps_data = 0; /* set the flag - Socket does not keep item data */
366
+ conn->result_end = 1; /* set the flag - there are no items */
367
+ conn->in_query = 1;
368
+ if (conn->autocommit)
369
+ {
370
+ int comm_res = commit_handler(conn);
371
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
372
+ return SEDNA_ERROR;
373
+ }
374
+ return SEDNA_QUERY_SUCCEEDED;
375
+ }
376
+ else
377
+ {
378
+ connectionFailure(conn, SE3008, "Unknown message recieved while executing statement", NULL); /* "Unknown message from server" */
379
+ conn->socket_keeps_data = 0; /*set the flag - Socket keeps item data*/
380
+ conn->local_data_offset = 0;
381
+ conn->local_data_length = 0;
382
+ conn->result_end = 1; /*set the flag - there are no items*/
383
+ conn->in_query = 0;
384
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
385
+
386
+ return SEDNA_QUERY_FAILED;
387
+ }
388
+ }
389
+
390
+ /* Send file to the client.
391
+ * On an ERROR - returns 1 (in this case errorcode contains code of the error),
392
+ * else - returns 0 (in this case errorcode valueis undefined).
393
+ * This function is used for loading modules and bulk loading.
394
+ */
395
+ static int
396
+ bulkload (struct SednaConnection *conn,
397
+ int* errorcode)
398
+ {
399
+ /* Get full path and open file. */
400
+ UFile file_handle = U_INVALID_FD;
401
+ char cur_dir_abspath[SE_MAX_DIR_LENGTH+1];
402
+ char cfile_abspath[SE_MAX_DIR_LENGTH+1];
403
+ int already_read = 1, res = 1;
404
+ char *filename = conn->msg.body + 5;
405
+ filename[s_min(conn->msg.length - 5, SE_SOCKET_MSG_BUF_SIZE - 6)] = '\0';
406
+
407
+ /* Try firstly to find file in the session directory ... */
408
+ if (uGetCurrentWorkingDirectory(cur_dir_abspath, SE_MAX_DIR_LENGTH, NULL) == NULL) {
409
+ setDriverErrorMsg(conn, SE4602, cur_dir_abspath);
410
+ goto BulkLoadErr;
411
+ }
412
+ if (uChangeWorkingDirectory(conn->session_directory, NULL) != 0) {
413
+ setDriverErrorMsg(conn, SE4604, conn->session_directory);
414
+ goto BulkLoadErr;
415
+ }
416
+ if (uGetAbsoluteFilePath(filename, cfile_abspath, SE_MAX_DIR_LENGTH, NULL) != NULL) {
417
+
418
+ file_handle = uOpenFile(cfile_abspath, U_SHARE_READ, U_READ, 0, NULL);
419
+ }
420
+
421
+ /* restore working directory anyway */
422
+ if (uChangeWorkingDirectory(cur_dir_abspath, NULL) != 0) {
423
+ setDriverErrorMsg(conn, SE4604, cur_dir_abspath);
424
+ goto BulkLoadErr;
425
+ }
426
+
427
+ /* ... then try current directory ... */
428
+ if (file_handle == U_INVALID_FD &&
429
+ uGetAbsoluteFilePath(filename, cfile_abspath, SE_MAX_DIR_LENGTH, NULL) != NULL) {
430
+
431
+ file_handle = uOpenFile(cfile_abspath, U_SHARE_READ, U_READ, 0, NULL);
432
+ }
433
+
434
+ /* ... raise error if we still haven't found the file. */
435
+ if(file_handle == U_INVALID_FD) {
436
+ setDriverErrorMsg(conn, SE3017, filename);
437
+ goto BulkLoadErr;
438
+ }
439
+
440
+ /* Read data from file */
441
+ while ((res > 0) && (already_read != 0))
442
+ {
443
+ res = uReadFile(file_handle, conn->msg.body + 5, BULK_LOAD_PORTION, &already_read, NULL);
444
+ if (res == 0) {
445
+ setDriverErrorMsg(conn, SE3018, filename);
446
+ goto BulkLoadErr;
447
+ }
448
+
449
+ if (already_read == 0) break;
450
+
451
+ /* Send BulkLoadPortion (410) */
452
+ conn->msg.instruction = se_BulkLoadPortion;
453
+ conn->msg.length = 5 + already_read;
454
+ conn->msg.body[0] = 0;
455
+ int2net_int(already_read, conn->msg.body + 1);
456
+
457
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0) {
458
+ connectionFailure(conn, SE3006, "Connection was broken while application was passing bulk load portion to the server", NULL);
459
+ uCloseFile(file_handle, NULL);
460
+ goto SednaErr;
461
+ }
462
+ }
463
+
464
+ /* Close file */
465
+ if (!uCloseFile(file_handle, NULL)) {
466
+ setDriverErrorMsg(conn, SE3019, NULL);
467
+ goto SednaErr;
468
+ }
469
+
470
+ /* Send BulkLoadEnd (420) */
471
+ conn->msg.instruction = se_BulkLoadEnd;
472
+ conn->msg.length = 0;
473
+
474
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0) {
475
+ connectionFailure(conn, SE3006,
476
+ "Connection was broken while application was passing bulk load ending message to the server", NULL);
477
+ goto SednaErr;
478
+ }
479
+
480
+ return 0;
481
+
482
+ BulkLoadErr:
483
+ conn->msg.instruction = se_BulkLoadError;
484
+ conn->msg.length = 0;
485
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0) {
486
+ connectionFailure(conn, SE3006,
487
+ "Connection was broken while application was passing bulk load error to the server", NULL);
488
+ goto SednaErr;
489
+ }
490
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0) {
491
+ connectionFailure(conn, SE3007,
492
+ "Connection was broken while application was receiving response from the server", NULL);
493
+ goto SednaErr;
494
+ }
495
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
496
+ *errorcode = SEDNA_BULK_LOAD_FAILED;
497
+ return 1;
498
+
499
+ SednaErr:
500
+ *errorcode = SEDNA_ERROR;
501
+ return 1;
502
+ }
503
+
504
+ static int execute(struct SednaConnection *conn)
505
+ {
506
+ /* read 320 - QuerySucceeded, 330 - QueryFailed, 340 - UpdateSucceeded or 350 - UpdateFailed*/
507
+ /* or 430 - BulkLoadFileName, 431 - BulkLoadFromStream, 100 - ErrorResponse, */
508
+ /* or 325 - DebugInfo (retrieve all DebugInfo messages if there are) */
509
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
510
+ {
511
+ connectionFailure(conn, SE3007, "Connection was broken while executing statement", NULL);
512
+ return SEDNA_ERROR;
513
+ }
514
+
515
+ while (conn->msg.instruction == se_DebugInfo)
516
+ {
517
+ if (conn->debug_handler)
518
+ {
519
+ int length;
520
+ int debug_type;
521
+ char debug_info[SE_SOCKET_MSG_BUF_SIZE];
522
+ if (conn->msg.length <= 0)
523
+ {
524
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
525
+ return SEDNA_ERROR;
526
+ }
527
+ net_int2int(&debug_type, conn->msg.body);
528
+ net_int2int(&length, conn->msg.body + 5);
529
+ if (length <= 0)
530
+ {
531
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
532
+ return SEDNA_ERROR;
533
+ }
534
+ memcpy(debug_info, conn->msg.body + 9, length);
535
+ debug_info[length] = '\0';
536
+ conn->debug_handler(debug_type, debug_info);
537
+ }
538
+
539
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
540
+ {
541
+ connectionFailure(conn, SE3007, "Connection was broken while executing statement", NULL);
542
+ return SEDNA_ERROR;
543
+ }
544
+ }
545
+ if (conn->msg.instruction == se_ErrorResponse)
546
+ {
547
+ setServerErrorMsg(conn, conn->msg);
548
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
549
+ return SEDNA_ERROR;
550
+ }
551
+ else if (conn->msg.instruction == se_QuerySucceeded) /*QuerySucceeded*/
552
+ {
553
+ int query_result;
554
+ query_result = resultQueryHandler(conn);
555
+ conn->first_next = 1;
556
+ return query_result;
557
+ }
558
+ else if (conn->msg.instruction == se_QueryFailed) /*QueryFailed*/
559
+ {
560
+ setServerErrorMsg(conn, conn->msg);
561
+ conn->in_query = 0;
562
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
563
+ return SEDNA_QUERY_FAILED;
564
+ }
565
+ else if (conn->msg.instruction == se_UpdateSucceeded)
566
+ {
567
+ conn->in_query = 0;
568
+ if (conn->autocommit)
569
+ {
570
+ int comm_res = commit_handler(conn);
571
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
572
+ return SEDNA_UPDATE_FAILED;
573
+ }
574
+ return SEDNA_UPDATE_SUCCEEDED;
575
+ }
576
+ else if (conn->msg.instruction == se_UpdateFailed)
577
+ {
578
+ setServerErrorMsg(conn, conn->msg);
579
+ conn->in_query = 0;
580
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
581
+ return SEDNA_UPDATE_FAILED;
582
+ }
583
+ else if (conn->msg.instruction == se_BulkLoadFileName)
584
+ {
585
+ while(conn->msg.instruction == se_BulkLoadFileName)
586
+ {
587
+ int status = 0;
588
+
589
+ if ( bulkload(conn, &status) != 0 )
590
+ return status;
591
+
592
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0) {
593
+ connectionFailure(conn, SE3007, "Connection was broken while obtaining bulk load result", NULL);
594
+ return SEDNA_ERROR;
595
+ }
596
+ }
597
+
598
+ if (conn->msg.instruction == se_ErrorResponse)
599
+ {
600
+ setServerErrorMsg(conn, conn->msg);
601
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
602
+ return SEDNA_ERROR;
603
+ }
604
+ else if ((conn->msg.instruction == se_BulkLoadSucceeded) ||
605
+ (conn->msg.instruction == se_UpdateSucceeded))
606
+ {
607
+ conn->in_query = 0;
608
+ if (conn->autocommit)
609
+ {
610
+ int comm_res = commit_handler(conn);
611
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
612
+ return SEDNA_BULK_LOAD_FAILED;
613
+ }
614
+ return SEDNA_BULK_LOAD_SUCCEEDED;
615
+ }
616
+ else if ((conn->msg.instruction == se_UpdateFailed) ||
617
+ (conn->msg.instruction == se_BulkLoadFailed))
618
+ {
619
+ setServerErrorMsg(conn, conn->msg);
620
+ conn->in_query = 0;
621
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
622
+ return SEDNA_BULK_LOAD_FAILED;
623
+ }
624
+ else
625
+ {
626
+ /* Unknown message from server */
627
+ setDriverErrorMsg(conn, SE3008, NULL);
628
+ return SEDNA_ERROR;
629
+ }
630
+ }
631
+ else if (conn->msg.instruction == se_BulkLoadFromStream) /* Bulk Load from Stream */
632
+ {
633
+ conn->in_query = 0;
634
+ return SEDNA_UPDATE_FAILED;
635
+ }
636
+ else /* Unknown message from server */
637
+ {
638
+ connectionFailure(conn, SE3008, NULL, NULL);
639
+ return SEDNA_ERROR;
640
+ }
641
+ return SEDNA_ERROR;
642
+ }
643
+
644
+ /******************************************************************************
645
+ * Driver Functions Implementation
646
+ *****************************************************************************/
647
+
648
+ int SEconnect(struct SednaConnection *conn, const char *url, const char *db_name, const char *login, const char *password)
649
+ {
650
+ char host[SE_HOSTNAMELENGTH + 1];
651
+ int port = 5050, db_name_len = 0, login_len = 0, password_len = 0, url_len = 0;
652
+ int body_position = 0, host_len = 0, socket_optval = 1, socket_optsize = sizeof(int);
653
+
654
+ db_name_len = strlen(db_name);
655
+ login_len = strlen(login);
656
+ password_len = strlen(password);
657
+ url_len = strlen(url);
658
+
659
+ clearLastError(conn);
660
+
661
+ if (db_name_len > SE_MAX_DB_NAME_LENGTH)
662
+ {
663
+ connectionFailure(conn, SE3023, db_name, NULL);
664
+ return SEDNA_OPEN_SESSION_FAILED;
665
+ }
666
+ if (login_len > SE_MAX_LOGIN_LENGTH)
667
+ {
668
+ connectionFailure(conn, SE3024, login, NULL);
669
+ return SEDNA_OPEN_SESSION_FAILED;
670
+ }
671
+ if (password_len > SE_MAX_PASSWORD_LENGTH)
672
+ {
673
+ connectionFailure(conn, SE3025, password, NULL);
674
+ return SEDNA_OPEN_SESSION_FAILED;
675
+ }
676
+ if (url_len > SE_HOSTNAMELENGTH)
677
+ {
678
+ connectionFailure(conn, SE3026, url, NULL);
679
+ return SEDNA_OPEN_SESSION_FAILED;
680
+ }
681
+
682
+ conn->isConnectionOk = SEDNA_CONNECTION_CLOSED;
683
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
684
+
685
+ if (uSocketInit(NULL) != 0)
686
+ {
687
+ connectionFailure(conn, SE3016, NULL, NULL); /* Can't initialize socket library.*/
688
+ return SEDNA_OPEN_SESSION_FAILED;
689
+ }
690
+
691
+ conn->socket = usocket(AF_INET, SOCK_STREAM, 0, NULL);
692
+ if (conn->socket == U_INVALID_SOCKET)
693
+ {
694
+ connectionFailure(conn, SE3001, NULL, NULL); /* Failed to initialize a socket.*/
695
+ release(conn);
696
+ return SEDNA_OPEN_SESSION_FAILED;
697
+ }
698
+
699
+ if (usetsockopt(conn->socket, IPPROTO_TCP, TCP_NODELAY, (char *) &socket_optval, socket_optsize, NULL) == U_SOCKET_ERROR)
700
+ {
701
+ connectionFailure(conn, SE3027, NULL, NULL); /* Failed to set socket option.*/
702
+ release(conn);
703
+ return SEDNA_OPEN_SESSION_FAILED;
704
+ }
705
+
706
+ if (strstr(url, ":") != NULL)
707
+ {
708
+ host_len = strcspn(url, ":");
709
+ port = atoi(url + host_len + 1);
710
+ }
711
+ else
712
+ host_len = url_len;
713
+
714
+ if (_strnicmp(url, "localhost", host_len) == 0)
715
+ {
716
+ strcpy(host, "127.0.0.1");
717
+ }
718
+ else
719
+ {
720
+ memcpy(host, url, host_len);
721
+ host[host_len] = '\0';
722
+ }
723
+
724
+ if (uconnect_tcp(conn->socket, port, host, NULL) != 0)
725
+ {
726
+ connectionFailure(conn, SE3003, url, NULL); /* "Failed to connect to host specified"*/
727
+ release(conn);
728
+ return SEDNA_OPEN_SESSION_FAILED;
729
+ }
730
+
731
+ /* send a message for listener,*/
732
+ /* 110 - StartUp*/
733
+ conn->msg.instruction = se_StartUp;
734
+ conn->msg.length = 0;
735
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
736
+ {
737
+ connectionFailure(conn, SE3006, "Connection was broken while sending Start up mesage to server", NULL);
738
+ release(conn);
739
+ return SEDNA_OPEN_SESSION_FAILED;
740
+ }
741
+ /* read msg. 140 - SendSessionParameters*/
742
+ /* send protocol version, login, dbname. SessionParameters - 120*/
743
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
744
+ {
745
+ connectionFailure(conn, SE3007, "Connection was broken while recieve se_SendSessionParameters mesage from server", NULL);
746
+ release(conn);
747
+ return SEDNA_OPEN_SESSION_FAILED;
748
+ }
749
+ if (conn->msg.instruction == se_ErrorResponse)
750
+ {
751
+ connectionFailure(conn, 0, NULL, &(conn->msg));
752
+ release(conn);
753
+ return SEDNA_OPEN_SESSION_FAILED;
754
+ }
755
+ else if (conn->msg.instruction == se_SendSessionParameters)
756
+ {
757
+ conn->msg.instruction = se_SessionParameters; /*SessionParameters*/
758
+ /*body contains:*/
759
+ /*major protocol version*/
760
+ /*minor protocol version*/
761
+ /* login string*/
762
+ /*dbname string */
763
+ conn->msg.length = 2 + 5 + login_len + 5 + db_name_len;
764
+
765
+ /* writing protocol version 3.0*/
766
+ conn->msg.body[0] = SE_CURRENT_SOCKET_PROTOCOL_VERSION_MAJOR;
767
+ conn->msg.body[1] = SE_CURRENT_SOCKET_PROTOCOL_VERSION_MINOR;
768
+
769
+ /* writing login */
770
+ conn->msg.body[2] = 0; /* format code*/
771
+ int2net_int(login_len, conn->msg.body + 3);
772
+ memcpy(conn->msg.body + 7, login, login_len);
773
+ body_position += 7 + strlen(login);
774
+
775
+ /* writing db_name */
776
+ conn->msg.body[body_position] = 0; /* format code*/
777
+ int2net_int(db_name_len, conn->msg.body + body_position + 1);
778
+ body_position += 5;
779
+ memcpy(conn->msg.body + body_position, db_name, db_name_len);
780
+
781
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
782
+ {
783
+ connectionFailure(conn, SE3006, "Connection was broken while sending authorization data to the server", NULL);
784
+ release(conn);
785
+ return SEDNA_OPEN_SESSION_FAILED;
786
+ }
787
+ }
788
+ else
789
+ goto UnknownMsg;
790
+
791
+ /* read - error or SendAuthenticationParameters - 150*/
792
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
793
+ {
794
+ connectionFailure(conn, SE3007, "Connection was broken while recieving authorization request from the server", NULL);
795
+ release(conn);
796
+ return SEDNA_OPEN_SESSION_FAILED;
797
+ }
798
+
799
+ if (conn->msg.instruction == se_ErrorResponse)
800
+ {
801
+ connectionFailure(conn, 0, NULL, &(conn->msg));
802
+ release(conn);
803
+ return SEDNA_OPEN_SESSION_FAILED;
804
+ }
805
+ else if (conn->msg.instruction == se_SendAuthParameters)
806
+ {
807
+ /* send authentication paramaters - password. 130 - AuthenticationParameters*/
808
+ conn->msg.instruction = se_AuthenticationParameters; /*AuthenticationParameters*/
809
+ conn->msg.length = 5 + password_len;
810
+
811
+ /* writing password */
812
+ conn->msg.body[0] = 0; /* format code*/
813
+ int2net_int(password_len, conn->msg.body + 1);
814
+ memcpy(conn->msg.body + 5, password, password_len);
815
+
816
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
817
+ {
818
+ connectionFailure(conn, SE3006, "Connection was broken while sending authorization data to the server", NULL);
819
+ release(conn);
820
+ return SEDNA_OPEN_SESSION_FAILED;
821
+ }
822
+ }
823
+ else
824
+ goto UnknownMsg;
825
+
826
+ /* read AuthenticationOk - 160 or AuthenticationFailed - 170.*/
827
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
828
+ {
829
+ connectionFailure(conn, SE3007, "Connection was broken while recieving authorization result from the server", NULL);
830
+ release(conn);
831
+ return SEDNA_OPEN_SESSION_FAILED;
832
+ }
833
+ if (conn->msg.instruction == se_ErrorResponse)
834
+ {
835
+ connectionFailure(conn, 0, NULL, &(conn->msg));
836
+ release(conn);
837
+ return SEDNA_OPEN_SESSION_FAILED;
838
+ }
839
+ else if (conn->msg.instruction == se_AuthenticationFailed)
840
+ {
841
+ connectionFailure(conn, SE3053, NULL, NULL); /* "Authentication failed"*/
842
+ release(conn);
843
+ return SEDNA_AUTHENTICATION_FAILED;
844
+ }
845
+ else if (conn->msg.instruction == se_AuthenticationOK) /* AuthenticationOk*/
846
+ {
847
+ strcpy(conn->url, url);
848
+ strcpy(conn->db_name, db_name);
849
+ strcpy(conn->login, login);
850
+ strcpy(conn->password, password); /* Need to initialize every field */
851
+ strcpy(conn->query_time, "not available"); /* No time available */
852
+ conn->socket_keeps_data = 0;
853
+ conn->result_end = 0;
854
+ conn->in_query = 0;
855
+ conn->local_data_length = 0;
856
+ conn->local_data_offset = 0;
857
+ conn->cbl.bulk_load_started = 0;
858
+ if(strcmp(conn->session_directory, "") == 0) /* Session directory has not been set yet */
859
+ {
860
+ if (uGetCurrentWorkingDirectory(conn->session_directory, SE_MAX_DIR_LENGTH, NULL) == NULL)
861
+ {
862
+ connectionFailure(conn, SE4602, conn->session_directory, NULL);
863
+ release(conn);
864
+ return SEDNA_OPEN_SESSION_FAILED;
865
+ }
866
+ }
867
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
868
+ conn->isConnectionOk = SEDNA_CONNECTION_OK;
869
+
870
+ return SEDNA_SESSION_OPEN;
871
+ }
872
+
873
+ UnknownMsg:
874
+ connectionFailure(conn, SE3008, "Unknown message from server got while trying ot open a session", NULL); /* "Unknown message from server"*/
875
+ release(conn);
876
+ return SEDNA_OPEN_SESSION_FAILED;
877
+
878
+ }
879
+
880
+ int SEclose(struct SednaConnection *conn)
881
+ {
882
+ clearLastError(conn);
883
+
884
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
885
+ return SEDNA_SESSION_CLOSED;
886
+ if (conn->isConnectionOk == SEDNA_CONNECTION_FAILED)
887
+ {
888
+ release(conn);
889
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
890
+ conn->isConnectionOk = SEDNA_CONNECTION_CLOSED;
891
+ return SEDNA_SESSION_CLOSED;
892
+ }
893
+
894
+ /* clean socket*/
895
+ if (cleanSocket(conn) == SEDNA_ERROR)
896
+ {
897
+ release(conn);
898
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
899
+ conn->isConnectionOk = SEDNA_CONNECTION_CLOSED;
900
+ return SEDNA_ERROR;
901
+ }
902
+
903
+ if ((conn->autocommit) && (conn->isInTransaction == SEDNA_TRANSACTION_ACTIVE))
904
+ {
905
+ int comm_res = commit_handler(conn);
906
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
907
+ {
908
+ release(conn);
909
+ return SEDNA_CLOSE_SESSION_FAILED;
910
+ }
911
+ }
912
+
913
+ /* send 500 - CloseConnection*/
914
+ conn->msg.instruction = se_CloseConnection;
915
+ conn->msg.length = 0;
916
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
917
+ {
918
+ connectionFailure(conn, SE3006, "Connection was broken while trying to close session", NULL);
919
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
920
+ conn->isConnectionOk = SEDNA_CONNECTION_CLOSED;
921
+ release(conn);
922
+ return SEDNA_ERROR;
923
+ }
924
+
925
+ /* read 100 or 510 - CloseConnectionOk or 520 - TransactionRollbackBeforeClose*/
926
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
927
+ {
928
+ connectionFailure(conn, SE3007, "Connection was broken while trying to close session", NULL);
929
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
930
+ conn->isConnectionOk = SEDNA_CONNECTION_CLOSED;
931
+ release(conn);
932
+ return SEDNA_ERROR;
933
+ }
934
+
935
+ release(conn);
936
+ conn->isConnectionOk = SEDNA_CONNECTION_CLOSED;
937
+
938
+ if (conn->msg.instruction == se_ErrorResponse)
939
+ {
940
+ setServerErrorMsg(conn, conn->msg);
941
+ return SEDNA_CLOSE_SESSION_FAILED;
942
+ }
943
+ else if (conn->msg.instruction == se_TransactionRollbackBeforeClose) /*TransactionRollbackBeforeClose*/
944
+ {
945
+ setServerErrorMsg(conn, conn->msg);
946
+ return SEDNA_SESSION_CLOSED;
947
+ }
948
+ else if (conn->msg.instruction == se_CloseConnectionOk) /*CloseConnectionOk*/
949
+ {
950
+ return SEDNA_SESSION_CLOSED;
951
+ }
952
+ else
953
+ {
954
+ connectionFailure(conn, SE3008, "Unknown message got while trying to close session", NULL); /* "Unknown message from server" */
955
+ return SEDNA_CLOSE_SESSION_FAILED;
956
+ }
957
+ }
958
+
959
+ int SEbegin(struct SednaConnection *conn)
960
+ {
961
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
962
+ {
963
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
964
+ return SEDNA_ERROR;
965
+ }
966
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
967
+ return SEDNA_ERROR;
968
+
969
+ clearLastError(conn);
970
+
971
+ if (conn->autocommit)
972
+ {
973
+ setDriverErrorMsg(conn, SE3029, NULL); /* "This function call is prohibited as the connection is in the autocommit mode." */
974
+ return SEDNA_ERROR;
975
+ }
976
+
977
+ /* clean socket*/
978
+ if (cleanSocket(conn) == SEDNA_ERROR)
979
+ return SEDNA_ERROR;
980
+
981
+ return begin_handler(conn);
982
+ }
983
+
984
+ int SErollback(struct SednaConnection *conn)
985
+ {
986
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
987
+ {
988
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
989
+ return SEDNA_ERROR;
990
+ }
991
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
992
+ return SEDNA_ERROR;
993
+
994
+ if (conn->autocommit)
995
+ {
996
+ setDriverErrorMsg(conn, SE3029, NULL); /* "This function call is prohibited as the connection is in the autocommit mode." */
997
+ return SEDNA_ERROR;
998
+ }
999
+
1000
+ clearLastError(conn);
1001
+
1002
+ /* clean socket*/
1003
+ if (cleanSocket(conn) == SEDNA_ERROR)
1004
+ return SEDNA_ERROR;
1005
+
1006
+ return rollback_handler(conn);
1007
+ }
1008
+
1009
+ int SEcommit(struct SednaConnection *conn)
1010
+ {
1011
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1012
+ {
1013
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1014
+ return SEDNA_ERROR;
1015
+ }
1016
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1017
+ return SEDNA_ERROR;
1018
+
1019
+ if (conn->autocommit)
1020
+ {
1021
+ setDriverErrorMsg(conn, SE3029, NULL); /* "This function call is prohibited as the connection is in the autocommit mode." */
1022
+ return SEDNA_ERROR;
1023
+ }
1024
+
1025
+ clearLastError(conn);
1026
+
1027
+ /* clean socket*/
1028
+ if (cleanSocket(conn) == SEDNA_ERROR)
1029
+ return SEDNA_ERROR;
1030
+ conn->in_query = 0;
1031
+
1032
+ return commit_handler(conn);
1033
+ }
1034
+
1035
+ int SEexecuteLong(struct SednaConnection *conn, const char* query_file_path)
1036
+ {
1037
+ int read = 0;
1038
+ FILE* query_file;
1039
+
1040
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1041
+ {
1042
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1043
+ return SEDNA_ERROR;
1044
+ }
1045
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1046
+ return SEDNA_ERROR;
1047
+
1048
+ clearLastError(conn);
1049
+
1050
+ /* clean socket*/
1051
+ if (cleanSocket(conn) == SEDNA_ERROR)
1052
+ return SEDNA_ERROR;
1053
+
1054
+ /* if autocommit is on - begin transaction implicitly */
1055
+ if ((conn->autocommit) && (conn->isInTransaction == SEDNA_NO_TRANSACTION))
1056
+ {
1057
+ int begin_res = begin_handler(conn);
1058
+ if (begin_res != SEDNA_BEGIN_TRANSACTION_SUCCEEDED)
1059
+ return SEDNA_ERROR;
1060
+ }
1061
+
1062
+ if(NULL == query_file_path || (query_file = fopen(query_file_path, "rb")) == NULL)
1063
+ {
1064
+ setDriverErrorMsg(conn, SE3081, NULL); /* "Can't open file with long query to execute" */
1065
+ return SEDNA_ERROR;
1066
+ }
1067
+
1068
+ while ((read < SE_SOCKET_MSG_BUF_SIZE - 6) && (!feof(query_file)))
1069
+ {
1070
+ read += fread(conn->msg.body + 6 + read, sizeof(char), SE_SOCKET_MSG_BUF_SIZE - 6 - read, query_file);
1071
+ }
1072
+ if (feof(query_file))
1073
+ {
1074
+ conn->msg.instruction = se_Execute;
1075
+ conn->msg.body[0] = 0; /* result format code*/
1076
+ conn->msg.body[1] = 0; /* string format*/
1077
+ int2net_int(read, conn->msg.body + 2);
1078
+ conn->msg.length = read + 6; /* body containes: result format (sxml=1 or xml=0) - 1 byte)*/
1079
+ /* string format - 1 byte;*/
1080
+ /* string length - 4 bytes*/
1081
+ /* string*/
1082
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1083
+ {
1084
+ connectionFailure(conn, SE3006, "Connection was broken while sending long query to the server", NULL);
1085
+ return SEDNA_ERROR;
1086
+ }
1087
+ }
1088
+ else /* Long query - pass to server in parts*/
1089
+ {
1090
+ while (1)
1091
+ {
1092
+ /*send 301 - ExecuteLong*/
1093
+ conn->msg.instruction = se_ExecuteLong;
1094
+ conn->msg.body[0] = 0; /* result format code*/
1095
+ conn->msg.body[1] = 0; /* string format*/
1096
+ int2net_int(read, conn->msg.body + 2);
1097
+ conn->msg.length = read + 6; /* body containes: result format (sxml=1 or xml=0) - 1 byte)*/
1098
+ /* string format - 1 byte;*/
1099
+ /* string length - 4 bytes*/
1100
+ /* string*/
1101
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1102
+ {
1103
+ connectionFailure(conn, SE3006, "Connection was broken while sending long query to the server", NULL);
1104
+ return SEDNA_ERROR;
1105
+ }
1106
+ if (feof(query_file))
1107
+ break;
1108
+ read = fread(conn->msg.body + 6, sizeof(char), SE_SOCKET_MSG_BUF_SIZE - 6, query_file);
1109
+ }
1110
+ /*send 302 - LongQueryEnd*/
1111
+ conn->msg.instruction = se_LongQueryEnd;
1112
+ conn->msg.length = 0;
1113
+
1114
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1115
+ {
1116
+ connectionFailure(conn, SE3006, "Connection was broken while sending long query to the server", NULL);
1117
+ return SEDNA_ERROR;
1118
+ }
1119
+ }
1120
+
1121
+ fclose(query_file);
1122
+
1123
+ return execute(conn);
1124
+ }
1125
+
1126
+ int SEexecute(struct SednaConnection *conn, const char *query)
1127
+ {
1128
+ int query_length = 0, query_portion_size = 0, i = 0;
1129
+
1130
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1131
+ {
1132
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1133
+ return SEDNA_ERROR;
1134
+ }
1135
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1136
+ return SEDNA_ERROR;
1137
+
1138
+ clearLastError(conn);
1139
+
1140
+ /* clean socket*/
1141
+ if (cleanSocket(conn) == SEDNA_ERROR)
1142
+ return SEDNA_ERROR;
1143
+
1144
+ /* if autocommit is on - begin transaction implicitly */
1145
+ if ((conn->autocommit) && (conn->isInTransaction == SEDNA_NO_TRANSACTION))
1146
+ {
1147
+ int begin_res = begin_handler(conn);
1148
+ if (begin_res != SEDNA_BEGIN_TRANSACTION_SUCCEEDED)
1149
+ return SEDNA_ERROR;
1150
+ }
1151
+
1152
+ query_length = strlen(query);
1153
+ if (query_length > SE_SOCKET_MSG_BUF_SIZE - 6)
1154
+ {
1155
+ while (i < query_length)
1156
+ {
1157
+ /*send 301 - ExecuteLong*/
1158
+ conn->msg.instruction = se_ExecuteLong;
1159
+ conn->msg.body[0] = 0; /* result format code*/
1160
+ conn->msg.body[1] = 0; /* string format*/
1161
+ query_portion_size = ((query_length - i) >= (SE_SOCKET_MSG_BUF_SIZE - 6)) ? (SE_SOCKET_MSG_BUF_SIZE - 6) : (query_length - i);
1162
+ int2net_int(query_portion_size, conn->msg.body + 2);
1163
+
1164
+ memcpy(conn->msg.body + 6, query + i, query_portion_size);
1165
+
1166
+ conn->msg.length = query_portion_size + 6; /* body containes: result format (sxml=1 or xml=0) - 1 byte)*/
1167
+ /* string format - 1 byte;*/
1168
+ /* string length - 4 bytes*/
1169
+ /* string*/
1170
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1171
+ {
1172
+ connectionFailure(conn, SE3006, "Connection was broken while sending query to the server", NULL);
1173
+ return SEDNA_ERROR;
1174
+ }
1175
+
1176
+ i += query_portion_size;
1177
+ }
1178
+ /*send 302 - LongQueryEnd*/
1179
+ conn->msg.instruction = se_LongQueryEnd;
1180
+ conn->msg.length = 0;
1181
+
1182
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1183
+ {
1184
+ connectionFailure(conn, SE3006, "Connection was broken while sending query to the server", NULL);
1185
+ return SEDNA_ERROR;
1186
+ }
1187
+ }
1188
+ else
1189
+ {
1190
+ /*send 300 - ExecuteQuery*/
1191
+ conn->msg.instruction = se_Execute;
1192
+ conn->msg.length = query_length + 6; /* body containes: result format (sxml=1 or xml=0) - 1 byte)*/
1193
+ /* string format - 1 byte;*/
1194
+ /* string length - 4 bytes*/
1195
+ /* string*/
1196
+ conn->msg.body[0] = 0; /* result format code*/
1197
+ conn->msg.body[1] = 0; /* string format*/
1198
+ int2net_int(query_length, conn->msg.body + 2);
1199
+
1200
+ memcpy(conn->msg.body + 6, query, query_length);
1201
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1202
+ {
1203
+ connectionFailure(conn, SE3006, "Connection was broken while sending query to the server", NULL);
1204
+ return SEDNA_ERROR;
1205
+ }
1206
+ }
1207
+ return execute(conn);
1208
+ }
1209
+
1210
+
1211
+ int SEnext(struct SednaConnection *conn)
1212
+ {
1213
+ int res = 0;
1214
+
1215
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1216
+ {
1217
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1218
+ return SEDNA_ERROR;
1219
+ }
1220
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1221
+ return SEDNA_ERROR;
1222
+
1223
+ clearLastError(conn);
1224
+
1225
+ if (!conn->in_query)
1226
+ return SEDNA_NO_ITEM;
1227
+
1228
+ if (conn->result_end)
1229
+ {
1230
+ return SEDNA_RESULT_END;
1231
+ }
1232
+
1233
+ if (conn->first_next)
1234
+ {
1235
+ conn->first_next = 0;
1236
+ return SEDNA_NEXT_ITEM_SUCCEEDED;
1237
+ }
1238
+
1239
+ /* clean socket*/
1240
+ if (cleanSocket(conn) == SEDNA_ERROR)
1241
+ return SEDNA_ERROR;
1242
+
1243
+ conn->first_next = 0;
1244
+
1245
+ /*send GetNextItem - 310*/
1246
+ conn->msg.instruction = se_GetNextItem;
1247
+ conn->msg.length = 0;
1248
+
1249
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1250
+ {
1251
+ connectionFailure(conn, SE3006, "Connection was broken while sending Next command to the server", NULL);
1252
+ return SEDNA_ERROR;
1253
+ }
1254
+
1255
+ res = resultQueryHandler(conn);
1256
+ if ((res == SEDNA_QUERY_FAILED) || (res == SEDNA_ERROR))
1257
+ return SEDNA_NEXT_ITEM_FAILED;
1258
+ else if ((res == SEDNA_QUERY_SUCCEEDED) && (conn->result_end))
1259
+ return SEDNA_RESULT_END;
1260
+
1261
+ return SEDNA_NEXT_ITEM_SUCCEEDED;
1262
+ }
1263
+
1264
+ int SEgetData(struct SednaConnection *conn, char *buf, int bytes_to_read)
1265
+ {
1266
+ int buf_position = 0;
1267
+ int content_length = 0;
1268
+ char* content_offset = NULL;
1269
+
1270
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1271
+ {
1272
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1273
+ return SEDNA_ERROR;
1274
+ }
1275
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1276
+ return SEDNA_ERROR;
1277
+
1278
+ if ((!conn->in_query) || (conn->result_end))
1279
+ return 0;
1280
+
1281
+ clearLastError(conn);
1282
+
1283
+ if ((bytes_to_read < 0) || (buf == NULL))
1284
+ {
1285
+ setDriverErrorMsg(conn, SE3022, NULL); /* Invalid argument */
1286
+ conn->result_end = 1; /* Tell result is finished */
1287
+ conn->socket_keeps_data = 0; /* Tell there is no data in socket */
1288
+ return SEDNA_ERROR;
1289
+ }
1290
+ while (bytes_to_read > 0)
1291
+ {
1292
+ /*there is enough data strored locally in local buf*/
1293
+ if (bytes_to_read <= (conn->local_data_length - conn->local_data_offset))
1294
+ {
1295
+ memcpy(buf, conn->local_data_buf + conn->local_data_offset, bytes_to_read);
1296
+ conn->local_data_offset += bytes_to_read;
1297
+ return bytes_to_read;
1298
+ }
1299
+ /*local stored data is not enough - need to recv from server*/
1300
+ else
1301
+ {
1302
+ memcpy(buf + buf_position, conn->local_data_buf + conn->local_data_offset, conn->local_data_length - conn->local_data_offset);
1303
+ buf_position += conn->local_data_length - conn->local_data_offset;
1304
+ bytes_to_read -= conn->local_data_length - conn->local_data_offset;
1305
+ conn->local_data_length = 0;
1306
+ conn->local_data_offset = 0;
1307
+
1308
+ if (!conn->socket_keeps_data)
1309
+ {
1310
+ return buf_position;
1311
+ }
1312
+
1313
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1314
+ {
1315
+ connectionFailure(conn, SE3007, "Connection was broken while getting result data from the server", NULL);
1316
+ return SEDNA_ERROR;
1317
+ }
1318
+ if (conn->msg.instruction == se_ErrorResponse)
1319
+ {
1320
+ setServerErrorMsg(conn, conn->msg);
1321
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1322
+ conn->result_end = 1; /* tell result is finished*/
1323
+ conn->socket_keeps_data = 0; /* tell there is no data in socket*/
1324
+ return SEDNA_ERROR;
1325
+ }
1326
+ if (conn->msg.instruction == se_ItemPart) /* ItemPart */
1327
+ {
1328
+ content_length = conn->msg.length - 5;
1329
+ content_offset = conn->msg.body + 5;
1330
+
1331
+ if (content_length > bytes_to_read)
1332
+ {
1333
+ memcpy(buf + buf_position, content_offset, bytes_to_read);
1334
+ buf_position += bytes_to_read;
1335
+ memcpy(conn->local_data_buf, content_offset + bytes_to_read,
1336
+ content_length - bytes_to_read);
1337
+ conn->local_data_length = content_length - bytes_to_read;
1338
+ return buf_position;
1339
+ }
1340
+ else
1341
+ {
1342
+ memcpy(buf + buf_position, content_offset, content_length);
1343
+ buf_position += content_length;
1344
+ bytes_to_read -= content_length;
1345
+ }
1346
+ }
1347
+ else if (conn->msg.instruction == se_ItemEnd) /*ItemEnd*/
1348
+ {
1349
+ conn->socket_keeps_data = 0; /* tell there is no data in socket*/
1350
+ return buf_position;
1351
+ }
1352
+ else if (conn->msg.instruction == se_ResultEnd) /*ResultEnd*/
1353
+ {
1354
+ conn->result_end = 1; /* tell result is finished*/
1355
+ conn->socket_keeps_data = 0; /* tell there is no data in socket*/
1356
+ if (conn->autocommit)
1357
+ {
1358
+ int comm_res = commit_handler(conn);
1359
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
1360
+ return SEDNA_ERROR;
1361
+ }
1362
+
1363
+ return buf_position;
1364
+ }
1365
+ else
1366
+ {
1367
+ connectionFailure(conn, SE3008, "Unknown message got while getting result data from the server", NULL); /* "Unknown message from server" */
1368
+ conn->result_end = 1; /* tell result is finished*/
1369
+ conn->socket_keeps_data = 0; /* tell there is no data in socket*/
1370
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1371
+ conn->isConnectionOk = SEDNA_CONNECTION_FAILED;
1372
+ return SEDNA_ERROR;
1373
+ }
1374
+ } /* else */
1375
+
1376
+ } /* while */
1377
+ return buf_position;
1378
+ }
1379
+
1380
+ int SEloadData(struct SednaConnection *conn, const char *buf, int bytes_to_load, const char *doc_name, const char *col_name)
1381
+ {
1382
+ int bl_portion_size = 0, i = 0;
1383
+
1384
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1385
+ {
1386
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1387
+ return SEDNA_ERROR;
1388
+ }
1389
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1390
+ return SEDNA_ERROR;
1391
+
1392
+ clearLastError(conn);
1393
+
1394
+ if ((bytes_to_load <= 0) || (buf == NULL) || (doc_name == NULL) || (strlen(doc_name) == 0) || ((col_name != NULL) && (strlen(col_name) == 0)))
1395
+ {
1396
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1397
+ conn->result_end = 1; /* tell result is finished*/
1398
+ conn->socket_keeps_data = 0; /* tell there is no data in socket*/
1399
+ setBulkLoadFinished(conn);
1400
+ return SEDNA_ERROR;
1401
+ }
1402
+ /* clean socket*/
1403
+ if (cleanSocket(conn) == SEDNA_ERROR)
1404
+ return SEDNA_ERROR;
1405
+
1406
+ /* if autocommit is on - begin transaction implicitly */
1407
+ if ((conn->autocommit) && (conn->isInTransaction == SEDNA_NO_TRANSACTION))
1408
+ {
1409
+ int begin_res = begin_handler(conn);
1410
+ if (begin_res != SEDNA_BEGIN_TRANSACTION_SUCCEEDED)
1411
+ return SEDNA_ERROR;
1412
+ }
1413
+
1414
+ /* if bulk load of exactly this document is not started yet */
1415
+ if (!isBulkLoadStarted(conn))
1416
+ {
1417
+ char *query_str = NULL;
1418
+ int query_size = 0;
1419
+
1420
+ /*send 300 - ExecuteQuery*/
1421
+ conn->msg.instruction = 300;
1422
+ conn->msg.body[0] = 0; /* result format code*/
1423
+ conn->msg.body[1] = 0; /* string format*/
1424
+
1425
+ query_str = conn->msg.body + 6;
1426
+ if(conn->boundary_space_preserve)
1427
+ {
1428
+ strcpy(query_str, "declare boundary-space preserve;\n");
1429
+ strcat(query_str, "LOAD STDIN \"");
1430
+ }
1431
+ else
1432
+ strcpy(query_str, "LOAD STDIN \"");
1433
+
1434
+ strcat(query_str, doc_name);
1435
+ strcat(query_str, "\"");
1436
+ if (col_name != NULL)
1437
+ {
1438
+ strcat(query_str, " \"");
1439
+ strcat(query_str, col_name);
1440
+ strcat(query_str, "\"");
1441
+ }
1442
+ query_size = strlen(query_str);
1443
+
1444
+ int2net_int(query_size, conn->msg.body + 2);
1445
+ conn->msg.length = query_size + 6; /* body containes: result format (sxml=1 or xml=0) - 1 byte)*/
1446
+ /* string format - 1 byte;*/
1447
+ /* string length - 4 bytes*/
1448
+ /* string*/
1449
+
1450
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1451
+ {
1452
+ connectionFailure(conn, SE3006, "Connection was broken while loading data (bulk load) the server", NULL);
1453
+ return SEDNA_ERROR;
1454
+ }
1455
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1456
+ {
1457
+ connectionFailure(conn, SE3007, "Connection was broken while loading data (bulk load) the server", NULL);
1458
+ return SEDNA_ERROR;
1459
+ }
1460
+
1461
+ if (conn->msg.instruction == se_ErrorResponse)
1462
+ {
1463
+ setServerErrorMsg(conn, conn->msg);
1464
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1465
+ return SEDNA_ERROR;
1466
+ }
1467
+ else if (conn->msg.instruction != se_BulkLoadFromStream) /*BulkLoadFromStream*/
1468
+ {
1469
+ connectionFailure(conn, SE3008, NULL, NULL); /* "Unknown message from server" */
1470
+ return SEDNA_ERROR;
1471
+ }
1472
+
1473
+ setBulkLoadStarted(conn, doc_name, col_name);
1474
+ } /* bulk load started*/
1475
+
1476
+ /* if another document is currently loading */
1477
+ if(!isBulkLoadOf(conn, doc_name, col_name))
1478
+ {
1479
+ conn->msg.instruction = se_BulkLoadError; /*BulkLoadError*/
1480
+ int2net_int(SE4616, conn->msg.body);
1481
+ conn->msg.length = 4;
1482
+
1483
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1484
+ {
1485
+ connectionFailure(conn, SE3006, "Connection was broken while passing bulk load error to the server", NULL);
1486
+ return SEDNA_ERROR;
1487
+ }
1488
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1489
+ {
1490
+ connectionFailure(conn, SE3007, "Connection was broken while passing bulk load error to the server", NULL);
1491
+ return SEDNA_ERROR;
1492
+ }
1493
+ setBulkLoadFinished(conn);
1494
+ setDriverErrorMsg(conn, SE4616, NULL); /* Can't load a document because the session is loading another document. Finish current loading before beginning a new one. */
1495
+ return SEDNA_ERROR;
1496
+ }
1497
+
1498
+ i = 0;
1499
+ while (i < bytes_to_load)
1500
+ {
1501
+ conn->msg.instruction = se_BulkLoadPortion; /*BulkLoadPortion*/
1502
+ conn->msg.length = 0;
1503
+ bl_portion_size = ((bytes_to_load - i) >= (SE_SOCKET_MSG_BUF_SIZE - 5)) ? (SE_SOCKET_MSG_BUF_SIZE - 5) : (bytes_to_load - i);
1504
+ int2net_int(bl_portion_size, conn->msg.body + 1);
1505
+
1506
+ memcpy(conn->msg.body + 5, buf + i, bl_portion_size);
1507
+ conn->msg.length = bl_portion_size + 5; /* body containes: result format (sxml=1 or xml=0) - 1 byte)*/
1508
+ /* string format - 1 byte;*/
1509
+ /* string length - 4 bytes*/
1510
+ /* string*/
1511
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1512
+ {
1513
+ connectionFailure(conn, SE3006, "Connection was broken while passing a data chunk to the server", NULL);
1514
+ return SEDNA_ERROR;
1515
+ }
1516
+
1517
+ i += bl_portion_size;
1518
+ }
1519
+ return SEDNA_DATA_CHUNK_LOADED;
1520
+ }
1521
+
1522
+ int SEendLoadData(struct SednaConnection *conn)
1523
+ {
1524
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1525
+ {
1526
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1527
+ return SEDNA_ERROR;
1528
+ }
1529
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1530
+ return SEDNA_ERROR;
1531
+
1532
+ clearLastError(conn);
1533
+
1534
+ /* clean socket*/
1535
+ if (cleanSocket(conn) == SEDNA_ERROR)
1536
+ return SEDNA_ERROR;
1537
+
1538
+ conn->msg.instruction = se_BulkLoadEnd; /*BulkLoadEnd*/
1539
+ conn->msg.length = 0;
1540
+
1541
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1542
+ {
1543
+ connectionFailure(conn, SE3006, "Connection was broken while passing bulk load ending message to the server", NULL);
1544
+ return SEDNA_ERROR;
1545
+ }
1546
+
1547
+ setBulkLoadFinished(conn);
1548
+
1549
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1550
+ {
1551
+ connectionFailure(conn, SE3007, "Connection was broken while passing bulk load ending message to the server", NULL);
1552
+ return SEDNA_ERROR;
1553
+ }
1554
+
1555
+ if (conn->msg.instruction == se_ErrorResponse)
1556
+ {
1557
+ setServerErrorMsg(conn, conn->msg);
1558
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1559
+ return SEDNA_ERROR;
1560
+ }
1561
+ else if ((conn->msg.instruction == se_BulkLoadSucceeded) || (conn->msg.instruction == se_UpdateSucceeded)) /*BulkLoadSucceeded*/
1562
+ {
1563
+ conn->in_query = 0;
1564
+ if (conn->autocommit)
1565
+ {
1566
+ int comm_res = commit_handler(conn);
1567
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
1568
+ return SEDNA_BULK_LOAD_FAILED;
1569
+ }
1570
+ return SEDNA_BULK_LOAD_SUCCEEDED;
1571
+ }
1572
+ else if ((conn->msg.instruction == se_BulkLoadFailed) || (conn->msg.instruction == se_UpdateFailed)) /*BulkLoadFailed*/
1573
+ {
1574
+ conn->in_query = 0;
1575
+ setServerErrorMsg(conn, conn->msg);
1576
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1577
+ return SEDNA_BULK_LOAD_FAILED;
1578
+ }
1579
+ else
1580
+ {
1581
+ connectionFailure(conn, SE3008, "Unknown message got while passing bulk load ending message to the server", NULL); /* "Unknown message from server" */
1582
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1583
+ return SEDNA_BULK_LOAD_FAILED;
1584
+ }
1585
+ }
1586
+
1587
+ int SEgetLastErrorCode(struct SednaConnection *conn)
1588
+ {
1589
+ return conn->last_error;
1590
+ }
1591
+
1592
+ const char *SEgetLastErrorMsg(struct SednaConnection *conn)
1593
+ {
1594
+ if (conn->last_error != SEDNA_OPERATION_SUCCEEDED)
1595
+ return conn->last_error_msg;
1596
+ else
1597
+ return "";
1598
+ }
1599
+
1600
+ int SEconnectionStatus(struct SednaConnection *conn)
1601
+ {
1602
+ return conn->isConnectionOk;
1603
+ }
1604
+
1605
+ int SEtransactionStatus(struct SednaConnection *conn)
1606
+ {
1607
+ return conn->isInTransaction;
1608
+ }
1609
+
1610
+ const char *SEshowTime(struct SednaConnection *conn)
1611
+ {
1612
+ if (conn->isConnectionOk == SEDNA_CONNECTION_CLOSED)
1613
+ {
1614
+ setDriverErrorMsg(conn, SE3028, NULL); /* "Connection with server is closed or have not been established yet." */
1615
+ strcpy(conn->query_time, "not available");
1616
+ return conn->query_time;
1617
+ }
1618
+ if (conn->isConnectionOk != SEDNA_CONNECTION_OK)
1619
+ {
1620
+ strcpy(conn->query_time, "not available");
1621
+ return conn->query_time;
1622
+ }
1623
+
1624
+ /* clean socket*/
1625
+ if (cleanSocket(conn) == SEDNA_ERROR)
1626
+ {
1627
+ strcpy(conn->query_time, "not available");
1628
+ return conn->query_time;
1629
+ }
1630
+
1631
+ conn->msg.instruction = se_ShowTime; /*ShowTime*/
1632
+ conn->msg.length = 0;
1633
+
1634
+ clearLastError(conn);
1635
+
1636
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1637
+ {
1638
+ connectionFailure(conn, SE3006, "Connection was broken while obtaining execution time from the server", NULL);
1639
+ strcpy(conn->query_time, "not available");
1640
+ return conn->query_time;
1641
+ }
1642
+
1643
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1644
+ {
1645
+ connectionFailure(conn, SE3006, "Connection was broken while obtaining execution time from the server", NULL);
1646
+ strcpy(conn->query_time, "not available");
1647
+ return conn->query_time;
1648
+ }
1649
+
1650
+ if (conn->msg.instruction == se_LastQueryTime) /*LastQueryTime*/
1651
+ {
1652
+ strncpy(conn->query_time, conn->msg.body + 5, conn->msg.length - 5);
1653
+ conn->query_time[conn->msg.length - 5] = '\0';
1654
+ return conn->query_time;
1655
+ }
1656
+ else
1657
+ {
1658
+ strcpy(conn->query_time, "not available");
1659
+ return conn->query_time;
1660
+ }
1661
+ }
1662
+
1663
+ int SEsetConnectionAttr(struct SednaConnection *conn, enum SEattr attr, const void* attrValue, int attrValueLength)
1664
+ {
1665
+ int *value;
1666
+
1667
+ clearLastError(conn);
1668
+
1669
+ switch (attr){
1670
+ case SEDNA_ATTR_AUTOCOMMIT:
1671
+ value = (int*) attrValue;
1672
+ if ((*value != SEDNA_AUTOCOMMIT_OFF) && (*value != SEDNA_AUTOCOMMIT_ON))
1673
+ {
1674
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1675
+ return SEDNA_ERROR;
1676
+ }
1677
+ conn->autocommit = (*value == SEDNA_AUTOCOMMIT_ON) ? 1: 0;
1678
+ if ((*value == SEDNA_AUTOCOMMIT_ON) && (conn->isInTransaction == SEDNA_TRANSACTION_ACTIVE))
1679
+ {
1680
+ int comm_res = commit_handler(conn);
1681
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
1682
+ return SEDNA_ERROR;
1683
+ }
1684
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1685
+
1686
+ case SEDNA_ATTR_SESSION_DIRECTORY:
1687
+ if (attrValueLength > SE_MAX_DIR_LENGTH)
1688
+ {
1689
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1690
+ return SEDNA_ERROR;
1691
+ }
1692
+ strncpy(conn->session_directory, attrValue, attrValueLength);
1693
+ conn->session_directory[attrValueLength] = '\0';
1694
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1695
+
1696
+ case SEDNA_ATTR_DEBUG:
1697
+ conn->msg.instruction = se_SetSessionOptions; /*se_SetSessionOptions*/
1698
+ conn->msg.length = 9;
1699
+ value = (int*) attrValue;
1700
+ int2net_int(*value, conn->msg.body); //option type
1701
+ conn->msg.body[4] = 0;
1702
+ int2net_int(0, conn->msg.body+5); //length of the option value string = 0
1703
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1704
+ {
1705
+ connectionFailure(conn, SE3006, "Connection was broken while setting session option on the server", NULL);
1706
+ return SEDNA_ERROR;
1707
+ }
1708
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1709
+ {
1710
+ connectionFailure(conn, SE3007, "Connection was broken while setting session option on the server", NULL);
1711
+ return SEDNA_ERROR;
1712
+ }
1713
+ if (conn->msg.instruction == se_SetSessionOptionsOk)
1714
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1715
+ else if (conn->msg.instruction == se_ErrorResponse)
1716
+ {
1717
+ setServerErrorMsg(conn, conn->msg);
1718
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1719
+ return SEDNA_ERROR;
1720
+ }
1721
+ else
1722
+ {
1723
+ connectionFailure(conn, SE3008, "Unknown message got while setting session option on the server", NULL); /* "Unknown message from server" */
1724
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1725
+ return SEDNA_ERROR;
1726
+ }
1727
+ case SEDNA_ATTR_BOUNDARY_SPACE_PRESERVE_WHILE_LOAD:
1728
+ value = (int*) attrValue;
1729
+ if ((*value != SEDNA_BOUNDARY_SPACE_PRESERVE_OFF) && (*value != SEDNA_BOUNDARY_SPACE_PRESERVE_ON))
1730
+ {
1731
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1732
+ return SEDNA_ERROR;
1733
+ }
1734
+ conn->boundary_space_preserve = (*value == SEDNA_BOUNDARY_SPACE_PRESERVE_ON) ? 1: 0;
1735
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1736
+
1737
+ case SEDNA_ATTR_CONCURRENCY_TYPE:
1738
+ value = (int*) attrValue;
1739
+ if ((*value != SEDNA_READONLY_TRANSACTION) && (*value != SEDNA_UPDATE_TRANSACTION))
1740
+ {
1741
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1742
+ return SEDNA_ERROR;
1743
+ }
1744
+ // do force commit of existing transaction
1745
+ if (conn->isInTransaction == SEDNA_TRANSACTION_ACTIVE)
1746
+ {
1747
+ int comm_res = commit_handler(conn);
1748
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
1749
+ return SEDNA_ERROR;
1750
+ }
1751
+ conn->msg.instruction = se_SetSessionOptions; /*se_SetSessionOptions*/
1752
+ conn->msg.length = 9;
1753
+ int2net_int(*value, conn->msg.body); //option type
1754
+ conn->msg.body[4] = 0;
1755
+ int2net_int(0, conn->msg.body+5); //length of the option value string = 0
1756
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1757
+ {
1758
+ connectionFailure(conn, SE3006, "Connection was broken while setting session option on the server", NULL);
1759
+ return SEDNA_ERROR;
1760
+ }
1761
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1762
+ {
1763
+ connectionFailure(conn, SE3007, "Connection was broken while setting session option on the server", NULL);
1764
+ return SEDNA_ERROR;
1765
+ }
1766
+ if (conn->msg.instruction == se_SetSessionOptionsOk)
1767
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1768
+ else if (conn->msg.instruction == se_ErrorResponse)
1769
+ {
1770
+ setServerErrorMsg(conn, conn->msg);
1771
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1772
+ return SEDNA_ERROR;
1773
+ }
1774
+ else
1775
+ {
1776
+ connectionFailure(conn, SE3008, "Unknown message got while setting session option on the server", NULL); /* "Unknown message from server" */
1777
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1778
+ return SEDNA_ERROR;
1779
+ }
1780
+
1781
+ case SEDNA_ATTR_QUERY_EXEC_TIMEOUT:
1782
+ value = (int*) attrValue;
1783
+ if (*value < 0)
1784
+ {
1785
+ setDriverErrorMsg(conn, SE3022, "Timeout value must be > 0"); /* "Invalid argument."*/
1786
+ return SEDNA_ERROR;
1787
+ }
1788
+ conn->msg.instruction = se_SetSessionOptions; /*se_SetSessionOptions*/
1789
+ conn->msg.length = 13;
1790
+ int2net_int(SEDNA_QUERY_EXEC_TIMEOUT, conn->msg.body); //option type
1791
+ conn->msg.body[4] = 0;
1792
+ int2net_int(4, conn->msg.body+5); //length of value - here sizeof int = 4
1793
+ int2net_int(*value, conn->msg.body+9); //value of attribute - here int
1794
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1795
+ {
1796
+ connectionFailure(conn, SE3006, "Connection was broken while setting session option on the server", NULL);
1797
+ return SEDNA_ERROR;
1798
+ }
1799
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1800
+ {
1801
+ connectionFailure(conn, SE3007, "Connection was broken while setting session option on the server", NULL);
1802
+ return SEDNA_ERROR;
1803
+ }
1804
+ if (conn->msg.instruction == se_SetSessionOptionsOk)
1805
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1806
+ else if (conn->msg.instruction == se_ErrorResponse)
1807
+ {
1808
+ setServerErrorMsg(conn, conn->msg);
1809
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1810
+ return SEDNA_ERROR;
1811
+ }
1812
+ else
1813
+ {
1814
+ connectionFailure(conn, SE3008, "Unknown message got while setting session option on the server", NULL); /* "Unknown message from server" */
1815
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1816
+ return SEDNA_ERROR;
1817
+ }
1818
+ conn->query_timeout = *value;
1819
+
1820
+ case SEDNA_ATTR_LOG_AMMOUNT:
1821
+ value = (int*) attrValue;
1822
+ if ((*value != SEDNA_LOG_LESS) && (*value != SEDNA_LOG_FULL))
1823
+ {
1824
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1825
+ return SEDNA_ERROR;
1826
+ }
1827
+ // do force commit of existing transaction
1828
+ if (conn->isInTransaction == SEDNA_TRANSACTION_ACTIVE)
1829
+ {
1830
+ int comm_res = commit_handler(conn);
1831
+ if(comm_res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)
1832
+ return SEDNA_ERROR;
1833
+ }
1834
+ conn->msg.instruction = se_SetSessionOptions; /*se_SetSessionOptions*/
1835
+ conn->msg.length = 13;
1836
+ int2net_int(SEDNA_LOG_AMMOUNT, conn->msg.body); //option type
1837
+ conn->msg.body[4] = 0;
1838
+ int2net_int(4, conn->msg.body + 5); //length of value - here sizeof int = 4
1839
+ int2net_int(*value, conn->msg.body + 9); //value of attribute - here int
1840
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1841
+ {
1842
+ connectionFailure(conn, SE3006, "Connection was broken while setting session option on the server", NULL);
1843
+ return SEDNA_ERROR;
1844
+ }
1845
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1846
+ {
1847
+ connectionFailure(conn, SE3007, "Connection was broken while setting session option on the server", NULL);
1848
+ return SEDNA_ERROR;
1849
+ }
1850
+ if (conn->msg.instruction == se_SetSessionOptionsOk)
1851
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1852
+ else if (conn->msg.instruction == se_ErrorResponse)
1853
+ {
1854
+ setServerErrorMsg(conn, conn->msg);
1855
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1856
+ return SEDNA_ERROR;
1857
+ }
1858
+ else
1859
+ {
1860
+ connectionFailure(conn, SE3008, "Unknown message got while setting session option on the server", NULL); /* "Unknown message from server" */
1861
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1862
+ return SEDNA_ERROR;
1863
+ }
1864
+
1865
+ case SEDNA_ATTR_MAX_RESULT_SIZE:
1866
+ value = (int*) attrValue;
1867
+ if (*value < 0)
1868
+ {
1869
+ setDriverErrorMsg(conn, SE3022, "Max result size value must be > 0"); /* "Invalid argument."*/
1870
+ return SEDNA_ERROR;
1871
+ }
1872
+ conn->msg.instruction = se_SetSessionOptions; /*se_SetSessionOptions*/
1873
+ conn->msg.length = 13;
1874
+ int2net_int(SEDNA_MAX_RESULT_SIZE, conn->msg.body); //option type
1875
+ conn->msg.body[4] = 0;
1876
+ int2net_int(4, conn->msg.body+5); //length of value - here sizeof int = 4
1877
+ int2net_int(*value, conn->msg.body+9); //value of attribute - here int
1878
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1879
+ {
1880
+ connectionFailure(conn, SE3006, "Connection was broken while setting session option on the server", NULL);
1881
+ return SEDNA_ERROR;
1882
+ }
1883
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1884
+ {
1885
+ connectionFailure(conn, SE3007, "Connection was broken while setting session option on the server", NULL);
1886
+ return SEDNA_ERROR;
1887
+ }
1888
+ if (conn->msg.instruction == se_SetSessionOptionsOk)
1889
+ return SEDNA_SET_ATTRIBUTE_SUCCEEDED;
1890
+ else if (conn->msg.instruction == se_ErrorResponse)
1891
+ {
1892
+ setServerErrorMsg(conn, conn->msg);
1893
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1894
+ return SEDNA_ERROR;
1895
+ }
1896
+ else
1897
+ {
1898
+ connectionFailure(conn, SE3008, "Unknown message got while setting session option on the server", NULL); /* "Unknown message from server" */
1899
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1900
+ return SEDNA_ERROR;
1901
+ }
1902
+ conn->max_result_size = *value;
1903
+
1904
+ default:
1905
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1906
+ return SEDNA_ERROR;
1907
+ }
1908
+
1909
+ return SEDNA_ERROR;
1910
+ }
1911
+
1912
+ int SEgetConnectionAttr(struct SednaConnection *conn, enum SEattr attr, void* attrValue, int* attrValueLength)
1913
+ {
1914
+ int value;
1915
+
1916
+ clearLastError(conn);
1917
+
1918
+ switch (attr){
1919
+ case SEDNA_ATTR_AUTOCOMMIT:
1920
+ value = (conn->autocommit) ? SEDNA_AUTOCOMMIT_ON: SEDNA_AUTOCOMMIT_OFF;
1921
+ memcpy(attrValue, &value, 4);
1922
+ *attrValueLength = 4;
1923
+ return SEDNA_GET_ATTRIBUTE_SUCCEEDED;
1924
+ case SEDNA_ATTR_SESSION_DIRECTORY:
1925
+ memcpy(attrValue, conn->session_directory, strlen(conn->session_directory));
1926
+ *attrValueLength = strlen(conn->session_directory);
1927
+ return SEDNA_GET_ATTRIBUTE_SUCCEEDED;
1928
+ case SEDNA_ATTR_BOUNDARY_SPACE_PRESERVE_WHILE_LOAD:
1929
+ value = (conn->boundary_space_preserve) ? SEDNA_BOUNDARY_SPACE_PRESERVE_ON: SEDNA_BOUNDARY_SPACE_PRESERVE_OFF;
1930
+ memcpy(attrValue, &value, 4);
1931
+ *attrValueLength = 4;
1932
+ return SEDNA_GET_ATTRIBUTE_SUCCEEDED;
1933
+ case SEDNA_ATTR_QUERY_EXEC_TIMEOUT:
1934
+ value = (conn->query_timeout);
1935
+ memcpy(attrValue, &value, 4);
1936
+ *attrValueLength = 4;
1937
+ return SEDNA_GET_ATTRIBUTE_SUCCEEDED;
1938
+ case SEDNA_ATTR_MAX_RESULT_SIZE:
1939
+ value = (conn->max_result_size);
1940
+ memcpy(attrValue, &value, 4);
1941
+ *attrValueLength = 4;
1942
+ return SEDNA_GET_ATTRIBUTE_SUCCEEDED;
1943
+ default:
1944
+ setDriverErrorMsg(conn, SE3022, NULL); /* "Invalid argument."*/
1945
+ return SEDNA_ERROR;
1946
+ }
1947
+
1948
+ return SEDNA_ERROR;
1949
+ }
1950
+
1951
+ int SEresetAllConnectionAttr(struct SednaConnection *conn)
1952
+ {
1953
+ conn->autocommit = 1;
1954
+
1955
+ if (uGetCurrentWorkingDirectory(conn->session_directory, SE_MAX_DIR_LENGTH, NULL) == NULL)
1956
+ {
1957
+ connectionFailure(conn, SE4602, NULL, NULL);
1958
+ release(conn);
1959
+ return SEDNA_ERROR;
1960
+ }
1961
+
1962
+ /* Reset all options to their default values */
1963
+ conn->msg.instruction = se_ResetSessionOptions;
1964
+ conn->msg.length = 0;
1965
+ if (sp_send_msg(conn->socket, &(conn->msg)) != 0)
1966
+ {
1967
+ connectionFailure(conn, SE3006, "Connection was broken while resetting session option on the server", NULL);
1968
+ return SEDNA_ERROR;
1969
+ }
1970
+ if (sp_recv_msg(conn->socket, &(conn->msg)) != 0)
1971
+ {
1972
+ connectionFailure(conn, SE3007, "Connection was broken while resetting session option on the server", NULL);
1973
+ return SEDNA_ERROR;
1974
+ }
1975
+ if (conn->msg.instruction == se_ResetSessionOptionsOk)
1976
+ return SEDNA_RESET_ATTRIBUTES_SUCCEEDED;
1977
+ else if (conn->msg.instruction == se_ErrorResponse)
1978
+ {
1979
+ setServerErrorMsg(conn, conn->msg);
1980
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1981
+ return SEDNA_ERROR;
1982
+ }
1983
+ else
1984
+ {
1985
+ /* "Unknown message from server" */
1986
+ connectionFailure(conn, SE3008, "Unknown message got while resetting session option on the server", NULL);
1987
+ conn->isInTransaction = SEDNA_NO_TRANSACTION;
1988
+ return SEDNA_ERROR;
1989
+ }
1990
+
1991
+ return SEDNA_ERROR;
1992
+ }
1993
+
1994
+
1995
+ void SEsetDebugHandler(struct SednaConnection *conn, debug_handler_t _debug_handler_)
1996
+ {
1997
+ conn->debug_handler = _debug_handler_;
1998
+ }