jio 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +22 -0
- data/.travis.yml +18 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +19 -0
- data/LICENSE +16 -0
- data/README.rdoc +92 -0
- data/Rakefile +45 -0
- data/ext/jio/extconf.rb +123 -0
- data/ext/jio/file.c +488 -0
- data/ext/jio/file.h +20 -0
- data/ext/jio/jio_ext.c +119 -0
- data/ext/jio/jio_ext.h +46 -0
- data/ext/jio/jio_prelude.h +22 -0
- data/ext/jio/jruby.h +20 -0
- data/ext/jio/rubinius.h +22 -0
- data/ext/jio/ruby18.h +43 -0
- data/ext/jio/ruby19.h +15 -0
- data/ext/jio/transaction.c +260 -0
- data/ext/jio/transaction.h +26 -0
- data/ext/libjio.tar.gz +0 -0
- data/jio.gemspec +22 -0
- data/lib/jio.rb +12 -0
- data/lib/jio/file.rb +24 -0
- data/lib/jio/version.rb +5 -0
- data/test/helper.rb +32 -0
- data/test/test_file.rb +116 -0
- data/test/test_jio.rb +23 -0
- data/test/test_transaction.rb +111 -0
- metadata +90 -0
data/ext/jio/file.h
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifndef JIO_FILE_H
|
2
|
+
#define JIO_FILE_H
|
3
|
+
|
4
|
+
#define JIO_FILE_CLOSED 0x01
|
5
|
+
|
6
|
+
typedef struct {
|
7
|
+
jfs_t *fs;
|
8
|
+
int flags;
|
9
|
+
} jio_jfs_wrapper;
|
10
|
+
|
11
|
+
#define JioAssertFile(obj) JioAssertType(obj, rb_cJioFile, "JIO::File")
|
12
|
+
#define JioGetFile(obj) \
|
13
|
+
jio_jfs_wrapper *file = NULL; \
|
14
|
+
JioAssertFile(obj); \
|
15
|
+
Data_Get_Struct(obj, jio_jfs_wrapper, file); \
|
16
|
+
if (!file) rb_raise(rb_eTypeError, "uninitialized JIO file handle!");
|
17
|
+
|
18
|
+
void _init_rb_jio_file();
|
19
|
+
|
20
|
+
#endif
|
data/ext/jio/jio_ext.c
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
#include "jio_ext.h"
|
2
|
+
|
3
|
+
VALUE mJio;
|
4
|
+
VALUE rb_cJioFile;
|
5
|
+
VALUE rb_cJioTransaction;
|
6
|
+
|
7
|
+
VALUE jio_zero;
|
8
|
+
VALUE jio_empty_view;
|
9
|
+
|
10
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
11
|
+
rb_encoding *binary_encoding;
|
12
|
+
#endif
|
13
|
+
|
14
|
+
static VALUE jio_s_total;
|
15
|
+
static VALUE jio_s_invalid;
|
16
|
+
static VALUE jio_s_in_progress;
|
17
|
+
static VALUE jio_s_broken;
|
18
|
+
static VALUE jio_s_corrupt;
|
19
|
+
static VALUE jio_s_reapplied;
|
20
|
+
|
21
|
+
/*
|
22
|
+
* call-seq:
|
23
|
+
* JIO.check("/path/file", JIO::J_CLEANUP) => Hash
|
24
|
+
*
|
25
|
+
* Checks and repairs a file previously created and managed through libjio.
|
26
|
+
*
|
27
|
+
* === Examples
|
28
|
+
* JIO.check("/path/file", JIO::J_CLEANUP) => Hash
|
29
|
+
*
|
30
|
+
*/
|
31
|
+
|
32
|
+
static VALUE rb_jio_s_check(JIO_UNUSED VALUE jio, VALUE path, VALUE flags)
|
33
|
+
{
|
34
|
+
int ret;
|
35
|
+
VALUE result;
|
36
|
+
struct jfsck_result res;
|
37
|
+
Check_Type(path, T_STRING);
|
38
|
+
Check_Type(flags, T_FIXNUM);
|
39
|
+
ret = jfsck(RSTRING_PTR(path), NULL, &res, FIX2UINT(flags));
|
40
|
+
if (ret == J_ENOMEM) rb_memerror();
|
41
|
+
if (ret < 0) rb_sys_fail("jfsck");
|
42
|
+
result = rb_hash_new();
|
43
|
+
rb_hash_aset(result, jio_s_total, INT2NUM(res.total));
|
44
|
+
rb_hash_aset(result, jio_s_invalid, INT2NUM(res.invalid));
|
45
|
+
rb_hash_aset(result, jio_s_in_progress, INT2NUM(res.in_progress));
|
46
|
+
rb_hash_aset(result, jio_s_broken, INT2NUM(res.broken));
|
47
|
+
rb_hash_aset(result, jio_s_corrupt, INT2NUM(res.corrupt));
|
48
|
+
rb_hash_aset(result, jio_s_reapplied, INT2NUM(res.reapplied));
|
49
|
+
return result;
|
50
|
+
}
|
51
|
+
|
52
|
+
void
|
53
|
+
Init_jio_ext()
|
54
|
+
{
|
55
|
+
mJio = rb_define_module("JIO");
|
56
|
+
|
57
|
+
/*
|
58
|
+
* Generic globals (Fixnum 0 and empty Array for blank transaction views)
|
59
|
+
*/
|
60
|
+
jio_zero = INT2NUM(0);
|
61
|
+
rb_gc_register_address(&jio_empty_view);
|
62
|
+
jio_empty_view = rb_ary_new();
|
63
|
+
|
64
|
+
jio_s_total = ID2SYM(rb_intern("total"));
|
65
|
+
jio_s_invalid = ID2SYM(rb_intern("invalid"));
|
66
|
+
jio_s_in_progress = ID2SYM(rb_intern("in_progress"));
|
67
|
+
jio_s_broken = ID2SYM(rb_intern("broken"));
|
68
|
+
jio_s_corrupt = ID2SYM(rb_intern("corrupt"));
|
69
|
+
jio_s_reapplied = ID2SYM(rb_intern("reapplied"));
|
70
|
+
|
71
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
72
|
+
binary_encoding = rb_enc_find("binary");
|
73
|
+
#endif
|
74
|
+
|
75
|
+
/*
|
76
|
+
* Journal check specific constants
|
77
|
+
*/
|
78
|
+
rb_define_const(mJio, "J_ESUCCESS", INT2NUM(J_ESUCCESS));
|
79
|
+
rb_define_const(mJio, "J_ENOENT", INT2NUM(J_ENOENT));
|
80
|
+
rb_define_const(mJio, "J_ENOJOURNAL", INT2NUM(J_ENOJOURNAL));
|
81
|
+
rb_define_const(mJio, "J_ENOMEM", INT2NUM(J_ENOMEM));
|
82
|
+
rb_define_const(mJio, "J_ECLEANUP", INT2NUM(J_ECLEANUP));
|
83
|
+
rb_define_const(mJio, "J_EIO", INT2NUM(J_EIO));
|
84
|
+
|
85
|
+
/*
|
86
|
+
* jfscheck specific constants
|
87
|
+
*/
|
88
|
+
rb_define_const(mJio, "J_CLEANUP", INT2NUM(J_CLEANUP));
|
89
|
+
|
90
|
+
/*
|
91
|
+
* Open specific constants (POSIX)
|
92
|
+
*/
|
93
|
+
rb_define_const(mJio, "RDONLY", INT2NUM(O_RDONLY));
|
94
|
+
rb_define_const(mJio, "WRONLY", INT2NUM(O_WRONLY));
|
95
|
+
rb_define_const(mJio, "RDWR", INT2NUM(O_RDWR));
|
96
|
+
rb_define_const(mJio, "CREAT", INT2NUM(O_CREAT));
|
97
|
+
rb_define_const(mJio, "EXCL", INT2NUM(O_EXCL));
|
98
|
+
rb_define_const(mJio, "TRUNC", INT2NUM(O_TRUNC));
|
99
|
+
rb_define_const(mJio, "APPEND", INT2NUM(O_APPEND));
|
100
|
+
rb_define_const(mJio, "NONBLOCK", INT2NUM(O_NONBLOCK));
|
101
|
+
rb_define_const(mJio, "NDELAY", INT2NUM(O_NDELAY));
|
102
|
+
rb_define_const(mJio, "SYNC", INT2NUM(O_SYNC));
|
103
|
+
rb_define_const(mJio, "ASYNC", INT2NUM(O_ASYNC));
|
104
|
+
|
105
|
+
/*
|
106
|
+
* lseek specific constants
|
107
|
+
*/
|
108
|
+
rb_define_const(mJio, "SEEK_SET", INT2NUM(SEEK_SET));
|
109
|
+
rb_define_const(mJio, "SEEK_CUR", INT2NUM(SEEK_CUR));
|
110
|
+
rb_define_const(mJio, "SEEK_END", INT2NUM(SEEK_END));
|
111
|
+
|
112
|
+
/*
|
113
|
+
* JIO module methods
|
114
|
+
*/
|
115
|
+
rb_define_module_function(mJio, "check", rb_jio_s_check, 2);
|
116
|
+
|
117
|
+
_init_rb_jio_file();
|
118
|
+
_init_rb_jio_transaction();
|
119
|
+
}
|
data/ext/jio/jio_ext.h
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#ifndef JIO_EXT_H
|
2
|
+
#define JIO_EXT_H
|
3
|
+
|
4
|
+
#include "libjio.h"
|
5
|
+
#include "trans.h"
|
6
|
+
#include "ruby.h"
|
7
|
+
#include <sys/types.h>
|
8
|
+
#include <sys/stat.h>
|
9
|
+
#include <fcntl.h>
|
10
|
+
#include <unistd.h>
|
11
|
+
|
12
|
+
/* Compiler specific */
|
13
|
+
|
14
|
+
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
15
|
+
#define JIO_UNUSED __attribute__ ((unused))
|
16
|
+
#define JIO_NOINLINE __attribute__ ((noinline))
|
17
|
+
#else
|
18
|
+
#define JIO_UNUSED
|
19
|
+
#define JIO_NOINLINE
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#include "jio_prelude.h"
|
23
|
+
|
24
|
+
#define JioAssertType(obj, type, desc) \
|
25
|
+
if (!rb_obj_is_kind_of(obj,type)) \
|
26
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s): %s", rb_obj_classname(obj), desc, RSTRING_PTR(rb_obj_as_string(obj)));
|
27
|
+
|
28
|
+
#define AssertOffset(off) \
|
29
|
+
Check_Type(off, T_FIXNUM); \
|
30
|
+
if (off < jio_zero) rb_raise(rb_eArgError, "offset must be >= 0"); \
|
31
|
+
|
32
|
+
#define AssertLength(len) \
|
33
|
+
Check_Type(len, T_FIXNUM); \
|
34
|
+
if (len < jio_zero) rb_raise(rb_eArgError, "length must be >= 0"); \
|
35
|
+
|
36
|
+
#include "file.h"
|
37
|
+
#include "transaction.h"
|
38
|
+
|
39
|
+
extern VALUE mJio;
|
40
|
+
extern VALUE rb_cJioFile;
|
41
|
+
extern VALUE rb_cJioTransaction;
|
42
|
+
|
43
|
+
extern VALUE jio_zero;
|
44
|
+
extern VALUE jio_empty_view;
|
45
|
+
|
46
|
+
#endif
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef JIO_PRELUDE_H
|
2
|
+
#define JIO_PRELUDE_H
|
3
|
+
|
4
|
+
#ifndef RFLOAT_VALUE
|
5
|
+
#define RFLOAT_VALUE(v) (RFLOAT(v)->value)
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#ifdef RUBINIUS
|
9
|
+
#include "rubinius.h"
|
10
|
+
#else
|
11
|
+
#ifdef JRUBY
|
12
|
+
#include "jruby.h"
|
13
|
+
#else
|
14
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
15
|
+
#include "ruby19.h"
|
16
|
+
#else
|
17
|
+
#include "ruby18.h"
|
18
|
+
#endif
|
19
|
+
#endif
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#endif
|
data/ext/jio/jruby.h
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifndef JIO_JRUBY_H
|
2
|
+
#define JIO_JRUBY_H
|
3
|
+
|
4
|
+
#include "st.h"
|
5
|
+
|
6
|
+
/* XXX */
|
7
|
+
#define JioEncode(str) str
|
8
|
+
#ifndef THREAD_PASS
|
9
|
+
#define THREAD_PASS rb_thread_schedule();
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#define TRAP_BEG
|
13
|
+
#define TRAP_END
|
14
|
+
|
15
|
+
#undef rb_errinfo
|
16
|
+
#define rb_errinfo() (rb_gv_get("$!"))
|
17
|
+
|
18
|
+
#define HAVE_RB_THREAD_BLOCKING_REGION 1
|
19
|
+
|
20
|
+
#endif
|
data/ext/jio/rubinius.h
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef JIO_RUBINIUS_H
|
2
|
+
#define JIO_RUBINIUS_H
|
3
|
+
|
4
|
+
#define RSTRING_NOT_MODIFIED
|
5
|
+
|
6
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
7
|
+
#include <ruby/st.h>
|
8
|
+
#include <ruby/encoding.h>
|
9
|
+
#include <ruby/io.h>
|
10
|
+
extern rb_encoding *binary_encoding;
|
11
|
+
#define JioEncode(str) rb_enc_associate(str, binary_encoding)
|
12
|
+
#else
|
13
|
+
#include "st.h"
|
14
|
+
#define JioEncode(str) str
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#define TRAP_BEG
|
18
|
+
#define TRAP_END
|
19
|
+
|
20
|
+
#define THREAD_PASS rb_thread_schedule();
|
21
|
+
|
22
|
+
#endif
|
data/ext/jio/ruby18.h
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#ifndef JIO_RUBY18_H
|
2
|
+
#define JIO_RUBY18_H
|
3
|
+
|
4
|
+
#define THREAD_PASS rb_thread_schedule();
|
5
|
+
#define JioEncode(str) str
|
6
|
+
#include "rubyio.h"
|
7
|
+
#include "rubysig.h"
|
8
|
+
#include "st.h"
|
9
|
+
|
10
|
+
#ifndef RSTRING_PTR
|
11
|
+
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
12
|
+
#endif
|
13
|
+
#ifndef RSTRING_LEN
|
14
|
+
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
15
|
+
#endif
|
16
|
+
|
17
|
+
/*
|
18
|
+
* partial emulation of the 1.9 rb_thread_blocking_region under 1.8,
|
19
|
+
* this is enough for dealing with blocking I/O functions in the
|
20
|
+
* presence of threads.
|
21
|
+
*/
|
22
|
+
|
23
|
+
#define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
|
24
|
+
typedef void rb_unblock_function_t(void *);
|
25
|
+
typedef VALUE rb_blocking_function_t(void *);
|
26
|
+
static VALUE
|
27
|
+
rb_thread_blocking_region(
|
28
|
+
rb_blocking_function_t *func, void *data1,
|
29
|
+
JIO_UNUSED rb_unblock_function_t *ubf,
|
30
|
+
JIO_UNUSED void *data2)
|
31
|
+
{
|
32
|
+
VALUE rv;
|
33
|
+
TRAP_BEG;
|
34
|
+
rv = func(data1);
|
35
|
+
TRAP_END;
|
36
|
+
return rv;
|
37
|
+
}
|
38
|
+
|
39
|
+
struct timeval rb_time_interval _((VALUE));
|
40
|
+
|
41
|
+
#define rb_errinfo() ruby_errinfo
|
42
|
+
|
43
|
+
#endif
|
data/ext/jio/ruby19.h
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef JIO_RUBY19_H
|
2
|
+
#define JIO_RUBY19_H
|
3
|
+
|
4
|
+
#include <ruby/encoding.h>
|
5
|
+
#include <ruby/io.h>
|
6
|
+
extern rb_encoding *binary_encoding;
|
7
|
+
#define JioEncode(str) rb_enc_associate(str, binary_encoding)
|
8
|
+
#ifndef THREAD_PASS
|
9
|
+
#define THREAD_PASS rb_thread_schedule();
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#define TRAP_BEG
|
13
|
+
#define TRAP_END
|
14
|
+
|
15
|
+
#endif
|
@@ -0,0 +1,260 @@
|
|
1
|
+
#include "jio_ext.h"
|
2
|
+
|
3
|
+
/*
|
4
|
+
* Generic transaction error handler
|
5
|
+
*/
|
6
|
+
static inline VALUE rb_jio_transaction_result(ssize_t ret, const char *ctx)
|
7
|
+
{
|
8
|
+
char err_buf[BUFSIZ];
|
9
|
+
if (ret >= 0) return Qtrue;
|
10
|
+
if (ret == -1) snprintf(err_buf, BUFSIZ, "JIO transaction error on %s (atomic warranties preserved)", ctx);
|
11
|
+
if (ret == -2) snprintf(err_buf, BUFSIZ, "JIO transaction error on %s (atomic warranties broken)", ctx);
|
12
|
+
rb_sys_fail(err_buf);
|
13
|
+
}
|
14
|
+
|
15
|
+
/*
|
16
|
+
* GC callbacks for JIO::Transaction
|
17
|
+
*/
|
18
|
+
void rb_jio_mark_transaction(void *ptr)
|
19
|
+
{
|
20
|
+
jio_jtrans_wrapper *trans = (jio_jtrans_wrapper *)ptr;
|
21
|
+
if (ptr) rb_gc_mark(trans->views);
|
22
|
+
}
|
23
|
+
|
24
|
+
void rb_jio_free_transaction(void *ptr)
|
25
|
+
{
|
26
|
+
jio_jtrans_wrapper *trans = (jio_jtrans_wrapper *)ptr;
|
27
|
+
if(trans) {
|
28
|
+
if (trans->trans != NULL && !(trans->flags & JIO_TRANSACTION_RELEASED)) jtrans_free(trans->trans);
|
29
|
+
xfree(trans);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
/*
|
34
|
+
* call-seq:
|
35
|
+
* transaction.read(2, 2) => boolean
|
36
|
+
*
|
37
|
+
* Reads X bytes from Y offset into a transaction view. The buffered data is only visible once the
|
38
|
+
* transaction has been committed.
|
39
|
+
*
|
40
|
+
* === Examples
|
41
|
+
* transaction.read(2, 2) => boolean
|
42
|
+
*
|
43
|
+
*/
|
44
|
+
|
45
|
+
static VALUE rb_jio_transaction_read(VALUE obj, VALUE length, VALUE offset)
|
46
|
+
{
|
47
|
+
int ret;
|
48
|
+
VALUE buf;
|
49
|
+
ssize_t len;
|
50
|
+
JioGetTransaction(obj);
|
51
|
+
AssertLength(length);
|
52
|
+
AssertOffset(offset);
|
53
|
+
len = (ssize_t)FIX2LONG(length);
|
54
|
+
buf = rb_str_new(0, len);
|
55
|
+
TRAP_BEG;
|
56
|
+
ret = jtrans_add_r(trans->trans, RSTRING_PTR(buf), len, (off_t)NUM2OFFT(offset));
|
57
|
+
TRAP_END;
|
58
|
+
if (ret == -1) rb_sys_fail("jtrans_add_r");
|
59
|
+
if (NIL_P(trans->views)) trans->views = rb_ary_new();
|
60
|
+
rb_ary_push(trans->views, JioEncode(buf));
|
61
|
+
return Qtrue;
|
62
|
+
}
|
63
|
+
|
64
|
+
/*
|
65
|
+
* call-seq:
|
66
|
+
* transaction.views => Array
|
67
|
+
*
|
68
|
+
* Returns a sequence of buffers representing previous transactional read operations. The result is
|
69
|
+
* always an empty Array if the transaction hasn't been committed yet. Operations will be applied in
|
70
|
+
* order, and overlapping operations are permitted, in which case the latest one will prevail.
|
71
|
+
*
|
72
|
+
* === Examples
|
73
|
+
* transaction.views => Array
|
74
|
+
*
|
75
|
+
*/
|
76
|
+
|
77
|
+
static VALUE rb_jio_transaction_views(VALUE obj)
|
78
|
+
{
|
79
|
+
jtrans_t *t = NULL;
|
80
|
+
JioGetTransaction(obj);
|
81
|
+
t = trans->trans;
|
82
|
+
if ((t->flags & J_COMMITTED) && !NIL_P(trans->views)) return trans->views;
|
83
|
+
return jio_empty_view;
|
84
|
+
}
|
85
|
+
|
86
|
+
/*
|
87
|
+
* call-seq:
|
88
|
+
* transaction.write("data", 2) => boolean
|
89
|
+
*
|
90
|
+
* Spawns a write operation from a given buffer to X offset for this transaction. Only written to disk
|
91
|
+
* when the transaction has been committed. Operations will be applied in order, and overlapping
|
92
|
+
* operations are permitted, in which case the latest one will prevail.
|
93
|
+
*
|
94
|
+
* === Examples
|
95
|
+
* transaction.write("data", 2) => boolean
|
96
|
+
*
|
97
|
+
*/
|
98
|
+
|
99
|
+
static VALUE rb_jio_transaction_write(VALUE obj, VALUE buf, VALUE offset)
|
100
|
+
{
|
101
|
+
int ret;
|
102
|
+
JioGetTransaction(obj);
|
103
|
+
Check_Type(buf, T_STRING);
|
104
|
+
AssertOffset(offset);
|
105
|
+
TRAP_BEG;
|
106
|
+
ret = jtrans_add_w(trans->trans, RSTRING_PTR(buf), (size_t)RSTRING_LEN(buf), (off_t)NUM2OFFT(offset));
|
107
|
+
TRAP_END;
|
108
|
+
if (ret == -1) rb_sys_fail("jtrans_add_w");
|
109
|
+
return Qtrue;
|
110
|
+
}
|
111
|
+
|
112
|
+
/*
|
113
|
+
* call-seq:
|
114
|
+
* transaction.commit => boolean
|
115
|
+
*
|
116
|
+
* Reads / writes all operations for this transaction to / from disk, in the order they were added.
|
117
|
+
* After this function returns successfully, all the data can be trusted to be on the disk. The commit
|
118
|
+
* is atomic with regards to other processes using libjio, but not accessing directly to the file.
|
119
|
+
*
|
120
|
+
* === Examples
|
121
|
+
* transaction.commit => boolean
|
122
|
+
*
|
123
|
+
*/
|
124
|
+
|
125
|
+
static VALUE rb_jio_transaction_commit(VALUE obj)
|
126
|
+
{
|
127
|
+
ssize_t ret;
|
128
|
+
JioGetTransaction(obj);
|
129
|
+
TRAP_BEG;
|
130
|
+
ret = jtrans_commit(trans->trans);
|
131
|
+
TRAP_END;
|
132
|
+
return rb_jio_transaction_result(ret, "commit");
|
133
|
+
}
|
134
|
+
|
135
|
+
/*
|
136
|
+
* call-seq:
|
137
|
+
* transaction.rollback => boolean
|
138
|
+
*
|
139
|
+
* This function atomically undoes a previous committed transaction. After its successful return, the
|
140
|
+
* data can be trusted to be on disk. The read operations will be ignored as we only care about on disk
|
141
|
+
* consistency.
|
142
|
+
*
|
143
|
+
* === Examples
|
144
|
+
* transaction.rollback => boolean
|
145
|
+
*
|
146
|
+
*/
|
147
|
+
|
148
|
+
static VALUE rb_jio_transaction_rollback(VALUE obj)
|
149
|
+
{
|
150
|
+
ssize_t ret;
|
151
|
+
VALUE res;
|
152
|
+
JioGetTransaction(obj);
|
153
|
+
TRAP_BEG;
|
154
|
+
ret = jtrans_rollback(trans->trans);
|
155
|
+
TRAP_END;
|
156
|
+
res = rb_jio_transaction_result(ret, "rollback");
|
157
|
+
if (!NIL_P(trans->views)) rb_ary_clear(trans->views);
|
158
|
+
return res;
|
159
|
+
}
|
160
|
+
|
161
|
+
/*
|
162
|
+
* call-seq:
|
163
|
+
* transaction.release => nil
|
164
|
+
*
|
165
|
+
* Free all transaction state and operation buffers
|
166
|
+
*
|
167
|
+
* === Examples
|
168
|
+
* transaction.release => nil
|
169
|
+
*
|
170
|
+
*/
|
171
|
+
|
172
|
+
static VALUE rb_jio_transaction_release(VALUE obj)
|
173
|
+
{
|
174
|
+
JioGetTransaction(obj);
|
175
|
+
TRAP_BEG;
|
176
|
+
jtrans_free(trans->trans);
|
177
|
+
TRAP_END;
|
178
|
+
trans->flags |= JIO_TRANSACTION_RELEASED;
|
179
|
+
return Qnil;
|
180
|
+
}
|
181
|
+
|
182
|
+
/*
|
183
|
+
* call-seq:
|
184
|
+
* transaction.committed? => boolean
|
185
|
+
*
|
186
|
+
* Determines if this transaction has been committed.
|
187
|
+
*
|
188
|
+
* === Examples
|
189
|
+
* transaction.committed? => boolean
|
190
|
+
*
|
191
|
+
*/
|
192
|
+
|
193
|
+
static VALUE rb_jio_transaction_committed_p(VALUE obj)
|
194
|
+
{
|
195
|
+
jtrans_t *t = NULL;
|
196
|
+
JioGetTransaction(obj);
|
197
|
+
t = trans->trans;
|
198
|
+
return (t->flags & J_COMMITTED) ? Qtrue : Qfalse;
|
199
|
+
}
|
200
|
+
|
201
|
+
/*
|
202
|
+
* call-seq:
|
203
|
+
* transaction.rollbacked? => boolean
|
204
|
+
*
|
205
|
+
* Determines if this transaction has been rolled back.
|
206
|
+
*
|
207
|
+
* === Examples
|
208
|
+
* transaction.rollbacked? => boolean
|
209
|
+
*
|
210
|
+
*/
|
211
|
+
|
212
|
+
static VALUE rb_jio_transaction_rollbacked_p(VALUE obj)
|
213
|
+
{
|
214
|
+
jtrans_t *t = NULL;
|
215
|
+
JioGetTransaction(obj);
|
216
|
+
t = trans->trans;
|
217
|
+
return (t->flags & J_ROLLBACKED) ? Qtrue : Qfalse;
|
218
|
+
}
|
219
|
+
|
220
|
+
/*
|
221
|
+
* call-seq:
|
222
|
+
* transaction.rollbacking? => boolean
|
223
|
+
*
|
224
|
+
* Determines if this transaction is in the process of being rolled back.
|
225
|
+
*
|
226
|
+
* === Examples
|
227
|
+
* transaction.rollbacking? => boolean
|
228
|
+
*
|
229
|
+
*/
|
230
|
+
|
231
|
+
static VALUE rb_jio_transaction_rollbacking_p(VALUE obj)
|
232
|
+
{
|
233
|
+
jtrans_t *t = NULL;
|
234
|
+
JioGetTransaction(obj);
|
235
|
+
t = trans->trans;
|
236
|
+
return (t->flags & J_ROLLBACKING) ? Qtrue : Qfalse;
|
237
|
+
}
|
238
|
+
|
239
|
+
void _init_rb_jio_transaction()
|
240
|
+
{
|
241
|
+
rb_define_const(mJio, "J_NOLOCK", INT2NUM(J_NOLOCK));
|
242
|
+
rb_define_const(mJio, "J_NOROLLBACK", INT2NUM(J_NOROLLBACK));
|
243
|
+
rb_define_const(mJio, "J_LINGER", INT2NUM(J_LINGER));
|
244
|
+
rb_define_const(mJio, "J_COMMITTED", INT2NUM(J_COMMITTED));
|
245
|
+
rb_define_const(mJio, "J_ROLLBACKED", INT2NUM(J_ROLLBACKED));
|
246
|
+
rb_define_const(mJio, "J_ROLLBACKING", INT2NUM(J_ROLLBACKING));
|
247
|
+
rb_define_const(mJio, "J_RDONLY", INT2NUM(J_RDONLY));
|
248
|
+
|
249
|
+
rb_cJioTransaction = rb_define_class_under(mJio, "Transaction", rb_cObject);
|
250
|
+
|
251
|
+
rb_define_method(rb_cJioTransaction, "read", rb_jio_transaction_read, 2);
|
252
|
+
rb_define_method(rb_cJioTransaction, "views", rb_jio_transaction_views, 0);
|
253
|
+
rb_define_method(rb_cJioTransaction, "write", rb_jio_transaction_write, 2);
|
254
|
+
rb_define_method(rb_cJioTransaction, "commit", rb_jio_transaction_commit, 0);
|
255
|
+
rb_define_method(rb_cJioTransaction, "rollback", rb_jio_transaction_rollback, 0);
|
256
|
+
rb_define_method(rb_cJioTransaction, "release", rb_jio_transaction_release, 0);
|
257
|
+
rb_define_method(rb_cJioTransaction, "committed?", rb_jio_transaction_committed_p, 0);
|
258
|
+
rb_define_method(rb_cJioTransaction, "rollbacked?", rb_jio_transaction_rollbacked_p, 0);
|
259
|
+
rb_define_method(rb_cJioTransaction, "rollbacking?", rb_jio_transaction_rollbacking_p, 0);
|
260
|
+
}
|