intersys 0.0.2
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/README +0 -0
- data/lib/common.c +61 -0
- data/lib/database.c +90 -0
- data/lib/definition.c +575 -0
- data/lib/extconf.rb +20 -0
- data/lib/intersys.c +83 -0
- data/lib/intersys.h +154 -0
- data/lib/intersys.rb +419 -0
- data/lib/object.c +69 -0
- data/lib/query.c +153 -0
- data/test/object.rb +17 -0
- data/test/query.rb +12 -0
- data/test/reflection.rb +65 -0
- data/test/strings.rb +14 -0
- metadata +69 -0
data/lib/extconf.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "mkmf"
|
4
|
+
#CONFIG["CPP"] = "g++"
|
5
|
+
CONFIG["CC"] = "gcc -g"
|
6
|
+
|
7
|
+
|
8
|
+
alias :old_cpp_include :cpp_include
|
9
|
+
#def cpp_include(header)
|
10
|
+
# old_cpp_include(header) + <<-EOF
|
11
|
+
# int main(void) {
|
12
|
+
# }
|
13
|
+
#EOF
|
14
|
+
#end
|
15
|
+
#find_library "cbind", "cbind_alloc_db","/Applications/Cache/bin"
|
16
|
+
|
17
|
+
find_header "c_api.h", "/Applications/Cache/dev/cpp/include/", "/Developer/Examples/Cache/cpp/include/"
|
18
|
+
$CFLAGS << " -I/Applications/Cache/dev/cpp/include/ -I/Developer/Examples/Cache/cpp/include/ -Wall"
|
19
|
+
create_makefile 'intersys_cache'
|
20
|
+
|
data/lib/intersys.c
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
#include "intersys.h"
|
2
|
+
|
3
|
+
VALUE mIntersys, cDatabase, cQuery, cObject, cDefinition, cProperty, cMethod, cArgument, cObjectNotFound, cStatus;
|
4
|
+
VALUE cTime, cMarshallError, cUnMarshallError;
|
5
|
+
|
6
|
+
static VALUE my_debug(VALUE self) {
|
7
|
+
printf("Hi!\n");
|
8
|
+
return Qnil;
|
9
|
+
}
|
10
|
+
|
11
|
+
void Init_intersys_cache() {
|
12
|
+
rb_define_method(rb_mKernel, "my_debug", my_debug, 0);
|
13
|
+
rb_define_method(rb_cString, "to_wchar", string_to_wchar, 0);
|
14
|
+
rb_define_method(rb_cString, "from_wchar", string_from_wchar, 0);
|
15
|
+
|
16
|
+
|
17
|
+
mIntersys = rb_define_module("Intersys");
|
18
|
+
cObjectNotFound = rb_const_get(mIntersys, rb_intern("ObjectNotFound"));
|
19
|
+
cMarshallError = rb_const_get(mIntersys, rb_intern("MarshallError"));
|
20
|
+
cUnMarshallError = rb_const_get(mIntersys, rb_intern("UnMarshallError"));
|
21
|
+
cStatus = rb_const_get(mIntersys, rb_intern("Status"));
|
22
|
+
cTime = rb_const_get(rb_cObject, rb_intern("Time"));
|
23
|
+
|
24
|
+
|
25
|
+
cDatabase = rb_define_class_under(mIntersys, "Database", rb_cObject);
|
26
|
+
rb_define_alloc_func(cDatabase, intersys_base_s_allocate);
|
27
|
+
rb_define_method(cDatabase, "initialize", intersys_base_initialize, 1);
|
28
|
+
rb_define_method(cDatabase, "connect", intersys_base_connect, 1);
|
29
|
+
rb_define_method(cDatabase, "begin_db_transaction", intersys_base_start, 0);
|
30
|
+
rb_define_method(cDatabase, "start", intersys_base_start, 0);
|
31
|
+
rb_define_method(cDatabase, "commit_db_transaction", intersys_base_commit, 0);
|
32
|
+
rb_define_method(cDatabase, "commit", intersys_base_commit, 0);
|
33
|
+
rb_define_method(cDatabase, "rollback_db_transaction", intersys_base_rollback, 0);
|
34
|
+
rb_define_method(cDatabase, "rollback", intersys_base_rollback, 0);
|
35
|
+
rb_define_method(cDatabase, "level", intersys_base_level, 0);
|
36
|
+
|
37
|
+
cQuery = rb_define_class_under(mIntersys, "Query", rb_cObject);
|
38
|
+
rb_define_alloc_func(cQuery, intersys_query_s_allocate);
|
39
|
+
rb_define_method(cQuery, "native_initialize", intersys_query_initialize, 2);
|
40
|
+
rb_define_method(cQuery, "execute", intersys_query_execute, 0);
|
41
|
+
rb_define_method(cQuery, "fetch", intersys_query_fetch, 0);
|
42
|
+
rb_define_method(cQuery, "column_name", intersys_query_column_name, 1);
|
43
|
+
rb_define_method(cQuery, "get_data", intersys_query_get_data, 1);
|
44
|
+
rb_define_method(cQuery, "close", intersys_query_close, 0);
|
45
|
+
|
46
|
+
cObject = rb_define_class_under(mIntersys, "Object", rb_cObject);
|
47
|
+
rb_define_alloc_func(cObject, intersys_object_s_allocate);
|
48
|
+
rb_define_method(cObject, "initialize", intersys_object_initialize, 0);
|
49
|
+
rb_define_singleton_method(cObject, "create_intern", intersys_object_create, 0);
|
50
|
+
rb_define_singleton_method(cObject, "open_intern", intersys_object_open_by_id, 1);
|
51
|
+
|
52
|
+
cDefinition = rb_const_get(mIntersys, rb_intern("Definition"));
|
53
|
+
rb_define_alloc_func(cDefinition, intersys_definition_s_allocate);
|
54
|
+
rb_define_method(cDefinition, "intern_initialize", intersys_definition_initialize, 3);
|
55
|
+
rb_define_method(cDefinition, "cpp_type", intersys_definition_cpp_type, 0);
|
56
|
+
rb_define_method(cDefinition, "cache_type", intersys_definition_cache_type, 0);
|
57
|
+
rb_define_method(cDefinition, "name", intersys_definition_name, 0);
|
58
|
+
rb_define_method(cDefinition, "in_name", intersys_definition_in_name, 0);
|
59
|
+
|
60
|
+
cProperty = rb_const_get(mIntersys, rb_intern("Property"));
|
61
|
+
rb_define_method(cProperty, "initialize", intersys_property_initialize, 4);
|
62
|
+
rb_define_method(cProperty, "extract_retval!", intersys_method_extract_retval, 0);
|
63
|
+
rb_define_method(cProperty, "get", intersys_property_get, 0);
|
64
|
+
rb_define_method(cProperty, "set", intersys_property_set, 1);
|
65
|
+
rb_define_method(cProperty, "marshall!", intersys_argument_set, 1);
|
66
|
+
|
67
|
+
cMethod = rb_const_get(mIntersys, rb_intern("Method"));
|
68
|
+
rb_define_method(cMethod, "method_initialize", intersys_method_initialize, 1);
|
69
|
+
rb_define_method(cMethod, "is_func?", intersys_method_is_func, 0);
|
70
|
+
rb_define_method(cMethod, "is_class_method?", intersys_method_is_class_method, 0);
|
71
|
+
rb_define_method(cMethod, "num_args", intersys_method_num_args, 0);
|
72
|
+
rb_define_method(cMethod, "prepare_call!", intersys_method_prepare_call, 0);
|
73
|
+
rb_define_method(cMethod, "intern_call!", intersys_method_call, 0);
|
74
|
+
rb_define_method(cMethod, "extract_retval!", intersys_method_extract_retval, 0);
|
75
|
+
|
76
|
+
cArgument = rb_const_get(mIntersys, rb_intern("Argument"));
|
77
|
+
rb_define_method(cArgument, "initialize", intersys_argument_initialize, 4);
|
78
|
+
rb_define_method(cArgument, "default", intersys_argument_default_value, 0);
|
79
|
+
rb_define_method(cArgument, "marshall_dlist_element", intersys_argument_marshall_dlist_elem, 1);
|
80
|
+
rb_define_method(cArgument, "marshall!", intersys_argument_set, 1);
|
81
|
+
// printf("Inited\n");
|
82
|
+
}
|
83
|
+
|
data/lib/intersys.h
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
#ifndef __cache_ruby
|
2
|
+
#define __cache_ruby
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
#include "rubyio.h"
|
6
|
+
#include "intern.h"
|
7
|
+
#include <time.h>
|
8
|
+
#include <c_api.h>
|
9
|
+
|
10
|
+
struct rbDatabase {
|
11
|
+
h_connection connection;
|
12
|
+
h_database database;
|
13
|
+
};
|
14
|
+
|
15
|
+
struct rbQuery {
|
16
|
+
h_query query;
|
17
|
+
bool_t empty;
|
18
|
+
};
|
19
|
+
|
20
|
+
struct rbObject {
|
21
|
+
h_database database;
|
22
|
+
int oref;
|
23
|
+
VALUE class_name;
|
24
|
+
};
|
25
|
+
|
26
|
+
struct rbDefinition {
|
27
|
+
int type;
|
28
|
+
h_database database;
|
29
|
+
void *def;
|
30
|
+
short cpp_type;
|
31
|
+
h_class_def cl_def;
|
32
|
+
const wchar_t* cache_type;
|
33
|
+
const wchar_t* name;
|
34
|
+
wchar_t* in_name;
|
35
|
+
// Method definitions
|
36
|
+
bool_t is_func;
|
37
|
+
bool_t is_class_method;
|
38
|
+
int num_args;
|
39
|
+
void *args_info;
|
40
|
+
int arg_counter;
|
41
|
+
//Argument definitions
|
42
|
+
bool_t is_by_ref;
|
43
|
+
bool_t is_default;
|
44
|
+
const char* default_value;
|
45
|
+
long default_value_size;
|
46
|
+
int arg_number;
|
47
|
+
|
48
|
+
char* current_dlist;
|
49
|
+
int current_dlist_size;
|
50
|
+
VALUE class_name;
|
51
|
+
//Property definitions
|
52
|
+
int oref;
|
53
|
+
};
|
54
|
+
|
55
|
+
enum { D_PROPERTY, D_METHOD, D_ARGUMENT};
|
56
|
+
|
57
|
+
enum {
|
58
|
+
ERR_CONN_LINK_FAILURE = 461
|
59
|
+
};
|
60
|
+
|
61
|
+
|
62
|
+
extern VALUE mIntersys, cDatabase, cQuery, cObject, cDefinition, cProperty, cMethod, cArgument, cObjectNotFound, cStatus;
|
63
|
+
extern VALUE cTime, cMarshallError, cUnMarshallError;
|
64
|
+
|
65
|
+
|
66
|
+
/****** Common functions ******/
|
67
|
+
|
68
|
+
VALUE string_to_wchar(VALUE self);
|
69
|
+
int run(int error, char* file, int line);
|
70
|
+
VALUE string_from_wchar(VALUE self);
|
71
|
+
VALUE rb_wcstr_new(const wchar_t *w_str, const char_size_t len);
|
72
|
+
VALUE rb_wcstr_new2(const wchar_t *w_str);
|
73
|
+
VALUE wcstr_new(const wchar_t *w_str, const char_size_t len);
|
74
|
+
|
75
|
+
/******* Database functions *******/
|
76
|
+
|
77
|
+
VALUE intersys_base_s_allocate(VALUE klass);
|
78
|
+
VALUE intersys_base_initialize(VALUE self, VALUE options);
|
79
|
+
VALUE intersys_base_connect(VALUE self, VALUE options);
|
80
|
+
VALUE intersys_base_start(VALUE self);
|
81
|
+
VALUE intersys_base_commit(VALUE self);
|
82
|
+
VALUE intersys_base_rollback(VALUE self);
|
83
|
+
VALUE intersys_base_level(VALUE self);
|
84
|
+
|
85
|
+
|
86
|
+
/******* Query functions *******/
|
87
|
+
|
88
|
+
VALUE intersys_query_s_allocate(VALUE klass);
|
89
|
+
VALUE intersys_query_initialize(VALUE self, VALUE database, VALUE sql_query);
|
90
|
+
VALUE intersys_query_execute(VALUE self);
|
91
|
+
VALUE intersys_query_column_name(VALUE self, VALUE index);
|
92
|
+
VALUE intersys_query_get_data(VALUE self, VALUE index);
|
93
|
+
VALUE intersys_query_fetch(VALUE self);
|
94
|
+
VALUE intersys_query_close(VALUE self);
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
/******* Object functions *******/
|
99
|
+
|
100
|
+
VALUE intersys_object_s_allocate(VALUE klass);
|
101
|
+
VALUE intersys_object_initialize(VALUE self);
|
102
|
+
VALUE intersys_object_open_by_id(VALUE self, VALUE oid);
|
103
|
+
VALUE intersys_object_create(VALUE self);
|
104
|
+
|
105
|
+
|
106
|
+
/******* Properties, definitions, arguments, methods functions *******/
|
107
|
+
|
108
|
+
VALUE intersys_definition_s_allocate(VALUE klass);
|
109
|
+
VALUE intersys_definition_initialize(VALUE self, VALUE r_database, VALUE class_name, VALUE name);
|
110
|
+
VALUE intersys_definition_cpp_type(VALUE self);
|
111
|
+
VALUE intersys_definition_cache_type(VALUE self);
|
112
|
+
VALUE intersys_definition_name(VALUE self);
|
113
|
+
VALUE intersys_definition_in_name(VALUE self);
|
114
|
+
VALUE intersys_property_initialize(VALUE self, VALUE r_database, VALUE class_name, VALUE name, VALUE object);
|
115
|
+
VALUE intersys_property_get(VALUE self);
|
116
|
+
VALUE intersys_property_set(VALUE self, VALUE value);
|
117
|
+
VALUE intersys_method_initialize(VALUE self, VALUE object);
|
118
|
+
VALUE intersys_method_is_func(VALUE self);
|
119
|
+
VALUE intersys_method_is_class_method(VALUE self);
|
120
|
+
VALUE intersys_method_num_args(VALUE self);
|
121
|
+
VALUE intersys_method_prepare_call(VALUE self);
|
122
|
+
VALUE intersys_method_call(VALUE self);
|
123
|
+
VALUE intersys_method_extract_retval(VALUE self);
|
124
|
+
VALUE intersys_argument_initialize(VALUE self, VALUE r_database, VALUE class_name, VALUE name, VALUE r_method);
|
125
|
+
VALUE intersys_argument_default_value(VALUE self);
|
126
|
+
VALUE intersys_argument_marshall_dlist_elem(VALUE self, VALUE elem);
|
127
|
+
VALUE intersys_argument_set(VALUE self, VALUE obj);
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
#define RUN(x) run((x), __FILE__, __LINE__)
|
136
|
+
#define QUERY_RUN(x) {int sql_code = 0; (x); run(sql_code, __FILE__, __LINE__);}
|
137
|
+
#define STR(x) (RSTRING(x)->ptr)
|
138
|
+
#define LEN(x) (RSTRING(x)->len)
|
139
|
+
#define CALL(x, method) (rb_funcall((x), rb_intern(method), 0))
|
140
|
+
|
141
|
+
#define WCHARSTR(x) ((wchar_t *)STR(x))
|
142
|
+
|
143
|
+
#define FROMWCHAR(x) (rb_funcall((x), rb_intern("from_wchar"), 0))
|
144
|
+
#define TOWCHAR(x) (rb_funcall((x), rb_intern("to_wchar"), 0))
|
145
|
+
|
146
|
+
#define FROMWCSTR(x) (FROMWCHAR(rb_wcstr_new2(x))) // From wchar_t* -> VALUE with utf8
|
147
|
+
#define PRINTABLE(x) STR(FROMWCHAR(x)) // from VALUE with ucs -> char * with utf8
|
148
|
+
#define CLASS_NAME(x) WCHARSTR((x)->class_name) // from object description -> wchar_t*
|
149
|
+
|
150
|
+
#define DLISTSIZE (argument->current_dlist_amount - argument->current_dlist_size)
|
151
|
+
#define PUT_DLIST(func, value) RUN(func(argument->current_dlist, DLISTSIZE, value, &elem_size))
|
152
|
+
|
153
|
+
|
154
|
+
#endif /* __cache_ruby */
|
data/lib/intersys.rb
ADDED
@@ -0,0 +1,419 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'dl/import'
|
3
|
+
require 'rubygems'
|
4
|
+
require_gem 'activesupport'
|
5
|
+
require 'active_support'
|
6
|
+
|
7
|
+
#
|
8
|
+
# Module, keeping all classes, required to work with Cache via object and SQL interfaces
|
9
|
+
module Intersys
|
10
|
+
extend DL::Importable
|
11
|
+
dlload("/Applications/Cache/bin/libcbind.dylib")
|
12
|
+
|
13
|
+
# Basic exception, thrown in intersys driver
|
14
|
+
class IntersysException < StandardError
|
15
|
+
end
|
16
|
+
|
17
|
+
# Exception, thrown from Object.open method, when no such ID in database
|
18
|
+
class ObjectNotFound < IntersysException
|
19
|
+
end
|
20
|
+
|
21
|
+
# Error of marshalling arguments
|
22
|
+
class MarshallError < IntersysException
|
23
|
+
end
|
24
|
+
|
25
|
+
# Error of unmarshalling results
|
26
|
+
class UnMarshallError < IntersysException
|
27
|
+
end
|
28
|
+
|
29
|
+
# Error establishing connection with database
|
30
|
+
class ConnectionError < IntersysException
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.handle_error(error_code, message, file, line)
|
34
|
+
#raise ConnectionError if error_code == 461
|
35
|
+
end
|
36
|
+
|
37
|
+
# Basic class for arguments, methods and properties description
|
38
|
+
# for internal use only
|
39
|
+
class Definition
|
40
|
+
def initialize(database, class_name, name)
|
41
|
+
@database = database
|
42
|
+
@class_name = class_name
|
43
|
+
@name = name
|
44
|
+
intern_initialize(database, class_name, name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Class representing one object property
|
49
|
+
# for internal use only
|
50
|
+
class Property < Definition
|
51
|
+
end
|
52
|
+
|
53
|
+
# Class representing one object method
|
54
|
+
# for internal use only
|
55
|
+
class Method < Definition
|
56
|
+
attr_accessor :args
|
57
|
+
protected
|
58
|
+
def arg!
|
59
|
+
Argument.new(@database, @class_name, @name, self)
|
60
|
+
end
|
61
|
+
public
|
62
|
+
|
63
|
+
def initialize(database, class_name, name, object)
|
64
|
+
super(database, class_name, name.to_s)
|
65
|
+
method_initialize(object)
|
66
|
+
@args = []
|
67
|
+
num_args.times do
|
68
|
+
@args << arg!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def call(*method_args)
|
73
|
+
prepare_call!
|
74
|
+
raise ArgumentError, "wrong number of arguments (#{method_args.size} for #{args.size})" if method_args.size > args.size
|
75
|
+
args.each_with_index do |arg, i|
|
76
|
+
arg.marshall!(method_args[i])
|
77
|
+
end
|
78
|
+
intern_call!
|
79
|
+
extract_retval!
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Class representing one method argument
|
84
|
+
# for internal use only
|
85
|
+
class Argument < Definition
|
86
|
+
def marshall_dlist(list)
|
87
|
+
list.each do |elem|
|
88
|
+
marshall_dlist_element(elem)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Method can return Cache %Status. It is marshalled to this class
|
94
|
+
class Status
|
95
|
+
attr_accessor :code
|
96
|
+
attr_accessor :message
|
97
|
+
def initialize(code, message)
|
98
|
+
@code = code
|
99
|
+
@message = message
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
require File.dirname(__FILE__) + '/intersys_cache'
|
104
|
+
|
105
|
+
|
106
|
+
# Basic class for all classes, through which is performed access to Cache classes
|
107
|
+
# For each Cache class must be created ruby class, inherited from Intersys::Object
|
108
|
+
#
|
109
|
+
# By default prefix "User" is selected. If Cache class has another prefix, it must
|
110
|
+
# be provided explicitly via method "prefix":
|
111
|
+
# class List < Intersys::Object
|
112
|
+
# prefix "%Library"
|
113
|
+
# end
|
114
|
+
#
|
115
|
+
# By default name of Cache class is taken the same as name of ruby class.
|
116
|
+
# Thus in this example this class List will be marshalled to Cache class
|
117
|
+
# %Library.List
|
118
|
+
#
|
119
|
+
class Object
|
120
|
+
|
121
|
+
class << self
|
122
|
+
protected
|
123
|
+
def class_names
|
124
|
+
common_get_or_set("@class_names", {})
|
125
|
+
end
|
126
|
+
|
127
|
+
def prefix=(name)
|
128
|
+
@prefix = name
|
129
|
+
@class_name = @prefix + "." + (@class_name ? @class_name.split(".").last : self.to_s)
|
130
|
+
register_name!
|
131
|
+
end
|
132
|
+
|
133
|
+
def class_name=(name)
|
134
|
+
if name.index(".")
|
135
|
+
self.prefix = name.split(".").first
|
136
|
+
@class_name = name
|
137
|
+
else
|
138
|
+
@class_name = self.prefix + "." + name
|
139
|
+
end
|
140
|
+
register_name!
|
141
|
+
end
|
142
|
+
|
143
|
+
# Register class name of current class in global list
|
144
|
+
def register_name!
|
145
|
+
if i = class_names.index(self)
|
146
|
+
class_names.delete(i)
|
147
|
+
end
|
148
|
+
class_names[class_name] = self
|
149
|
+
class_name
|
150
|
+
end
|
151
|
+
public
|
152
|
+
# Help to work with instance variables of Intersys::Object class
|
153
|
+
# required, because list of registered descendants of Intersys::Object,
|
154
|
+
# database connection etc. should be in one place
|
155
|
+
def common_get_or_set(name, default_value = nil)
|
156
|
+
unless var = Intersys::Object.instance_variable_get(name)
|
157
|
+
default = block_given? ? yield : default_value
|
158
|
+
var = Intersys::Object.instance_variable_set(name, default)
|
159
|
+
end
|
160
|
+
var
|
161
|
+
end
|
162
|
+
|
163
|
+
# Takes Cache class name and try to resolve it to Ruby class
|
164
|
+
def lookup(class_name)
|
165
|
+
class_names[class_name] || raise(UnMarshallError, "Couldn't find registered class with Cache name '#{class_name}'")
|
166
|
+
end
|
167
|
+
|
168
|
+
# Each Cache class has prefix before it's name: namespace.
|
169
|
+
# this method set's prefix for current class is provided,
|
170
|
+
# or just returns current prefix
|
171
|
+
def prefix(name = nil)
|
172
|
+
self.prefix = name if name
|
173
|
+
@prefix ||= "User"
|
174
|
+
end
|
175
|
+
|
176
|
+
def class_name(name = nil)
|
177
|
+
self.class_name = name if name
|
178
|
+
self.class_name = (prefix + "." + to_s) unless @class_name
|
179
|
+
@class_name
|
180
|
+
end
|
181
|
+
|
182
|
+
def database(db = nil)
|
183
|
+
common_get_or_set("@database") do
|
184
|
+
db || Intersys::Database.new(:user => "_SYSTEM", :password => "SYS", :namespace => "User")
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# This method takes block and executes it between
|
189
|
+
# START TRANSACTION and COMMIT TRANSACTION
|
190
|
+
#
|
191
|
+
# In case of exception ROLLBACK TRANSACTION is called
|
192
|
+
def transaction
|
193
|
+
return unless block_given?
|
194
|
+
database.start
|
195
|
+
begin
|
196
|
+
yield
|
197
|
+
database.commit
|
198
|
+
rescue StandardError => e
|
199
|
+
database.rollback
|
200
|
+
raise e
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Returns ClassDefinition object for current class
|
205
|
+
def reflector
|
206
|
+
@reflector ||= Intersys::Reflection::ClassDefinition.open(class_name)
|
207
|
+
end
|
208
|
+
|
209
|
+
# returns list of methods for this class
|
210
|
+
def intersys_methods
|
211
|
+
@methods ||= reflector.intersys_get("Methods")
|
212
|
+
end
|
213
|
+
|
214
|
+
# returns list of properties for current class
|
215
|
+
def intersys_properties
|
216
|
+
@properties ||= reflector.properties
|
217
|
+
end
|
218
|
+
|
219
|
+
def inherited(klass)
|
220
|
+
class_names[klass.class_name] = klass
|
221
|
+
end
|
222
|
+
|
223
|
+
def concurrency
|
224
|
+
1
|
225
|
+
end
|
226
|
+
|
227
|
+
# timeout for connection
|
228
|
+
def timeout
|
229
|
+
5
|
230
|
+
end
|
231
|
+
|
232
|
+
# create new instance of this class
|
233
|
+
def create
|
234
|
+
create_intern
|
235
|
+
end
|
236
|
+
|
237
|
+
# try to load class instance from database for this id
|
238
|
+
# ID can be not integer
|
239
|
+
def open(id)
|
240
|
+
open_intern(id.to_s.to_wchar)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Loads property definition with required name for required object
|
244
|
+
# for internal use only
|
245
|
+
def property(name, object)
|
246
|
+
Property.new(database, class_name, name.to_s.to_wchar, object)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Loads method definition with required name for required object
|
250
|
+
# for internal use only
|
251
|
+
def method(name, object)
|
252
|
+
Method.new(database, class_name, name.to_s.to_wchar, object)
|
253
|
+
end
|
254
|
+
|
255
|
+
# call class method
|
256
|
+
def call(method_name, *args)
|
257
|
+
method(method_name, nil).call(*args)
|
258
|
+
end
|
259
|
+
alias :intersys_call :call
|
260
|
+
#def self.method_missing(method_name, *args)
|
261
|
+
#end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
# Get the specified property
|
266
|
+
def intersys_get(property)
|
267
|
+
self.class.property(property, self).get
|
268
|
+
end
|
269
|
+
|
270
|
+
# Set the specified property
|
271
|
+
def intersys_set(property, value)
|
272
|
+
self.class.property(property, self).set(value)
|
273
|
+
end
|
274
|
+
|
275
|
+
# Call the specified method
|
276
|
+
def intersys_call(method, *args)
|
277
|
+
self.class.method(method, self).call(*args)
|
278
|
+
end
|
279
|
+
|
280
|
+
def method_missing(method, *args)
|
281
|
+
method_name = method.to_s.camelize
|
282
|
+
if match_data = method_name.match(/(\w+)=/)
|
283
|
+
return intersys_set(match_data.captures.first, args.first)
|
284
|
+
end
|
285
|
+
begin
|
286
|
+
return intersys_get(method_name)
|
287
|
+
rescue StandardError => e
|
288
|
+
puts e
|
289
|
+
begin
|
290
|
+
return intersys_call(method_name, *args)
|
291
|
+
rescue
|
292
|
+
end
|
293
|
+
end
|
294
|
+
super(method, *args)
|
295
|
+
end
|
296
|
+
|
297
|
+
def save
|
298
|
+
intersys_call("%Save")
|
299
|
+
end
|
300
|
+
|
301
|
+
# Returns id of current object
|
302
|
+
def id
|
303
|
+
intersys_call("%Id").to_i
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
# Class representing one query
|
308
|
+
# You shouldn't create it yourself
|
309
|
+
class Query
|
310
|
+
attr_reader :database
|
311
|
+
|
312
|
+
def initialize(database, query)
|
313
|
+
@database = database
|
314
|
+
native_initialize(database, query.to_wchar)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# Class representing Cache database connection
|
319
|
+
class Database
|
320
|
+
def create_query(query)
|
321
|
+
Query.new(self, query)
|
322
|
+
end
|
323
|
+
|
324
|
+
# This method creates SQL query, runs it, restores data
|
325
|
+
# and closes query
|
326
|
+
def query(query)
|
327
|
+
q = create_query(query).execute
|
328
|
+
data = []
|
329
|
+
while (row = q.fetch) && row.size > 0
|
330
|
+
data << row
|
331
|
+
end
|
332
|
+
q.close
|
333
|
+
1.upto(data.first.size) do |i|
|
334
|
+
puts q.column_name(i)
|
335
|
+
end
|
336
|
+
data
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# Module reflection keeps classes required to get information
|
341
|
+
# about methods and properties of Cache classes
|
342
|
+
module Reflection
|
343
|
+
|
344
|
+
# This class is basic reflection class
|
345
|
+
# If has class method Open(class_name), that creates instance of
|
346
|
+
# this class, representing its internals
|
347
|
+
#
|
348
|
+
# Usually creates via Intersys::Object.reflector
|
349
|
+
#
|
350
|
+
# Then it is possible to call such methods as _methods, properties
|
351
|
+
# to get access to methods and properties of Cache class
|
352
|
+
class ClassDefinition < Intersys::Object
|
353
|
+
class_name "%Dictionary.ClassDefinition"
|
354
|
+
|
355
|
+
# After all changes to class definition required to call save
|
356
|
+
def save
|
357
|
+
intersys_call("%Save")
|
358
|
+
end
|
359
|
+
|
360
|
+
# short alias to intersys_get("Methods")
|
361
|
+
def _methods
|
362
|
+
intersys_get("Methods")
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
class PropertyDefinition < Intersys::Object
|
367
|
+
class_name "%Dictionary.PropertyDefinition"
|
368
|
+
end
|
369
|
+
|
370
|
+
class MethodDefinition < Intersys::Object
|
371
|
+
class_name "%Dictionary.MethodDefinition"
|
372
|
+
end
|
373
|
+
|
374
|
+
# This is a proxy object to Cache RelationshipObject, which is just like Rails Association object
|
375
|
+
#
|
376
|
+
class RelationshipObject < Intersys::Object
|
377
|
+
class_name "%Library.RelationshipObject"
|
378
|
+
|
379
|
+
def empty?
|
380
|
+
intersys_call("IsEmpty")
|
381
|
+
end
|
382
|
+
|
383
|
+
def count
|
384
|
+
intersys_call("Count")
|
385
|
+
end
|
386
|
+
alias :size :count
|
387
|
+
|
388
|
+
def [](index)
|
389
|
+
intersys_call("GetAt", index.to_s)
|
390
|
+
end
|
391
|
+
|
392
|
+
def each
|
393
|
+
1.upto(count) do |i|
|
394
|
+
yield self[i]
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
def each_with_index
|
399
|
+
1.upto(count) do |i|
|
400
|
+
yield self[i], i
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
def inspect
|
405
|
+
list = []
|
406
|
+
each do |prop|
|
407
|
+
list << prop.name
|
408
|
+
end
|
409
|
+
list.inspect
|
410
|
+
end
|
411
|
+
alias :to_s :inspect
|
412
|
+
|
413
|
+
def <<(object)
|
414
|
+
intersys_call("Insert", object)
|
415
|
+
end
|
416
|
+
alias :insert :<<
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|