sedna 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/CHANGES +6 -0
  2. data/README +2 -2
  3. data/Rakefile +3 -3
  4. data/ext/sedna.c +36 -11
  5. data/test/sedna_test.rb +53 -0
  6. metadata +2 -2
data/CHANGES CHANGED
@@ -1,3 +1,9 @@
1
+ === 0.5.0
2
+
3
+ * Released on April 26th, 2009.
4
+ * Added Sedna::Exception#code, which returns the \Sedna error code that can
5
+ be used to reliably identify which specific error occurred.
6
+
1
7
  === 0.4.0
2
8
 
3
9
  * Released on January 4th, 2009.
data/README CHANGED
@@ -32,7 +32,7 @@ limitations under the License.
32
32
 
33
33
  === Current version
34
34
 
35
- The current version of this library is 0.4.0. This release is a <b>beta version</b>.
35
+ The current version of this library is 0.5.0. This is a <b>stable release</b>.
36
36
  For a complete overview all recent and previous changes, see CHANGES.
37
37
 
38
38
  === Requirements
@@ -51,7 +51,7 @@ library as a rubygem.
51
51
 
52
52
  % gem install sedna
53
53
 
54
- If the library or header files of the S<i></i>edna C driver are located at non-default
54
+ If the library or header files of the \Sedna C driver are located at non-default
55
55
  locations, you can specify these locations by adding the <tt>--with-sedna-lib</tt>
56
56
  or <tt>--with-sedna-include</tt> options when installing.
57
57
 
data/Rakefile CHANGED
@@ -57,7 +57,7 @@ end
57
57
 
58
58
  gem_spec = Gem::Specification.new do |s|
59
59
  s.name = "sedna"
60
- s.version = "0.4.0"
60
+ s.version = "0.5.0"
61
61
 
62
62
  s.summary = "Sedna XML DBMS client library."
63
63
  s.description = %{Ruby extension that provides a client library for the Sedna XML DBMS, making use of the official C driver of the Sedna project.}
@@ -84,8 +84,8 @@ Rake::GemPackageTask.new gem_spec do |p|
84
84
  p.need_zip = true
85
85
  end
86
86
 
87
- Rake::RDocTask.new { |rdoc|
87
+ Rake::RDocTask.new do |rdoc|
88
88
  rdoc.rdoc_dir = 'doc'
89
89
  rdoc.title = RDOC_TITLE
90
90
  rdoc.rdoc_files.include *RDOC_FILES
91
- }
91
+ end
data/ext/sedna.c CHANGED
@@ -62,6 +62,7 @@
62
62
  #define IV_PW "@password"
63
63
  #define IV_AUTOCOMMIT "@autocommit"
64
64
  #define IV_MUTEX "@mutex"
65
+ #define IV_EXC_CODE "@code"
65
66
 
66
67
  // Define a shorthand for the common SednaConnection structure.
67
68
  typedef struct SednaConnection SC;
@@ -129,43 +130,57 @@ static VALUE cSednaTrnError;
129
130
  // called that generated the error and should be passed as res.
130
131
  static void sedna_err(SC *conn, int res)
131
132
  {
132
- VALUE exception;
133
+ VALUE exc_class, exc;
133
134
  const char *msg;
134
- char *err, *details, *p;
135
+ char *code, *err, *details, *p, exc_message[BUFSIZ];
135
136
 
136
137
  switch(res) {
137
138
  case SEDNA_AUTHENTICATION_FAILED:
138
- exception = cSednaAuthError; break;
139
+ exc_class = cSednaAuthError; break;
139
140
  case SEDNA_OPEN_SESSION_FAILED:
140
141
  case SEDNA_CLOSE_SESSION_FAILED:
141
- exception = cSednaConnError; break;
142
+ exc_class = cSednaConnError; break;
142
143
  case SEDNA_BEGIN_TRANSACTION_FAILED:
143
144
  case SEDNA_ROLLBACK_TRANSACTION_FAILED:
144
145
  case SEDNA_COMMIT_TRANSACTION_FAILED:
145
- exception = cSednaTrnError; break;
146
+ exc_class = cSednaTrnError; break;
146
147
  case SEDNA_ERROR:
147
148
  default:
148
- exception = cSednaException;
149
+ exc_class = cSednaException;
149
150
  }
150
151
 
151
152
  msg = SEgetLastErrorMsg(conn);
153
+ // SEgetLastErrorCode(conn) is useless, because it varies if the order of
154
+ // errors changes. The actual code is a string which is defined in error_codes.h
155
+ // in the Sedna source code.
156
+ code = strstr(msg, "ERROR ");
152
157
  err = strstr(msg, "\n");
153
158
  details = strstr(err, "\nDetails: ");
154
159
 
160
+ if(code != NULL) {
161
+ code += 6; // Advance beyond "ERROR "
162
+ if((p = strstr(code, "\n")) != NULL) strncpy(p, "\0", 1);
163
+ }
164
+
155
165
  if(err != NULL) {
156
- err++;
166
+ err++; // Advance beyond "\n"
157
167
  if((p = strstr(err, "\n")) != NULL) strncpy(p, "\0", 1);
158
168
  } else {
159
169
  err = "Unknown error.";
160
170
  }
161
171
 
162
172
  if(details != NULL) {
163
- details += 10;
173
+ details += 10; // Advance beyond "\nDetails: "
164
174
  while((p = strstr(details, "\n")) != NULL) strncpy(p, " ", 1);
165
- rb_raise(exception, "%s (%s)", err, details);
175
+ snprintf(exc_message, BUFSIZ, "%s (%s)", err, details);
166
176
  } else {
167
- rb_raise(exception, "%s", err);
177
+ snprintf(exc_message, BUFSIZ, "%s", err);
168
178
  }
179
+ exc = rb_exc_new2(exc_class, exc_message);
180
+ if(code != NULL) {
181
+ rb_iv_set(exc, IV_EXC_CODE, rb_str_new2(code));
182
+ }
183
+ rb_exc_raise(exc);
169
184
  }
170
185
 
171
186
  // Retrieve the SednaConnection struct from the Ruby Sedna object obj.
@@ -982,7 +997,10 @@ void Init_sedna()
982
997
 
983
998
  /*
984
999
  * Generic exception class for errors. All errors raised by the \Sedna
985
- * client library are of type Sedna::Exception.
1000
+ * client library are of type Sedna::Exception. The original error code
1001
+ * can be retrieved with the +code+ attribute. A list of all error codes
1002
+ * is defined in the \Sedna source:
1003
+ * http://modis.ispras.ru/src/sedna/kernel/common/errdbg/error.codes
986
1004
  *
987
1005
  * === Subclasses
988
1006
  *
@@ -1000,6 +1018,13 @@ void Init_sedna()
1000
1018
  * Raised when a transaction could not be committed.
1001
1019
  */
1002
1020
  cSednaException = rb_define_class_under(cSedna, "Exception", rb_eStandardError);
1021
+ /*
1022
+ * Returns the error code associated with this exception. This code is a string
1023
+ * that can be used to accurately identify which error has occurred. Some
1024
+ * errors are thrown by the Ruby client rather than the C bindings. In these
1025
+ * cases, the error code is +nil+.
1026
+ */
1027
+ rb_define_attr(cSednaException, "code", 1, 0);
1003
1028
 
1004
1029
  /*
1005
1030
  * Sedna::AuthenticationError is a subclass of Sedna::Exception, and is
data/test/sedna_test.rb CHANGED
@@ -798,4 +798,57 @@ class SednaTest < Test::Unit::TestCase
798
798
  @@sedna.transaction
799
799
  assert_nil @@sedna.rollback
800
800
  end
801
+
802
+ # Test Sedna::Exception#code
803
+ test "code should return error code after connection failure" do
804
+ code = false
805
+ begin
806
+ Sedna.connect @@spec.merge(:username => "non-existent-user")
807
+ rescue Sedna::AuthenticationError => error
808
+ code = error.code
809
+ end
810
+ assert_equal "SE3053", code
811
+ end
812
+
813
+ test "code should return error code after trying to execute invalid statements" do
814
+ code = false
815
+ begin
816
+ @@sedna.execute "INVALID"
817
+ rescue Sedna::Exception => error
818
+ code = error.code
819
+ end
820
+ assert_equal "XPDY0002", code
821
+ end
822
+
823
+ test "code should return error code after trying to start a transaction within a transaction" do
824
+ code = false
825
+ @@sedna.transaction
826
+ begin
827
+ @@sedna.transaction
828
+ rescue Sedna::TransactionError => error
829
+ code = error.code
830
+ end
831
+ @@sedna.commit
832
+ assert_equal "SE4612", code
833
+ end
834
+
835
+ test "code should return error code after trying to load an invalid document" do
836
+ code = false
837
+ begin
838
+ @@sedna.load_document "<doc/> this is an invalid document", "some_doc"
839
+ rescue Sedna::Exception => error
840
+ code = error.code
841
+ end
842
+ assert_equal "SE2005", code
843
+ end
844
+
845
+ test "code should be nil if error is raised from inside the ruby client" do
846
+ code = false
847
+ begin
848
+ @@sedna.commit
849
+ rescue Sedna::TransactionError => error
850
+ code = error.code
851
+ end
852
+ assert_nil code
853
+ end
801
854
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sedna
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rolf Timmermans
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-04 00:00:00 +01:00
12
+ date: 2009-04-26 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15