carray-io-sqlite3 0.9.0
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.
- checksums.yaml +7 -0
- data/Rakefile +11 -0
- data/carray-io-sqlite3.gemspec +25 -0
- data/lib/carray-io-sqlite3.rb +3 -0
- data/lib/carray-io-sqlite3/core.rb +213 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0ac052de58e5cdff54847a23912e305b6782327c1723096a582155a2f1aa2d03
|
4
|
+
data.tar.gz: 0bb59ea60542e259947748b7067c6d0c859038825ef050f0a6f4c596a8deb9fc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a8a09074d9ddc25f3a32cf6b876c78327834c366ac1d975bc7dc0954eb404c6375bc42ae7d2699ea1f66163e5d6cb62afa66d452447aedcd27693c6458c46d81
|
7
|
+
data.tar.gz: d9ad878711a1d56db13314c995d9305517dd77a7515cc7f17bd852ae99059111bf43541bf027e8635dea79b2916eb8e95c381d5cef20118908cdb749ebe6219d
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Gem::Specification::new do |s|
|
2
|
+
version = "0.9.0"
|
3
|
+
files = Dir.glob("**/*") - [
|
4
|
+
Dir.glob("carray-io-sqlite3-*.gem"),
|
5
|
+
Dir.glob("test/**/*"),
|
6
|
+
Dir.glob("work/**/*"),
|
7
|
+
].flatten
|
8
|
+
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.name = "carray-io-sqlite3"
|
11
|
+
s.summary = "SQLite3 interface for CArray"
|
12
|
+
s.description = <<-HERE
|
13
|
+
SQLite3 interface for CArray
|
14
|
+
HERE
|
15
|
+
s.version = version
|
16
|
+
s.licenses = ['MIT']
|
17
|
+
s.author = "Hiroki Motoyoshi"
|
18
|
+
s.email = ""
|
19
|
+
s.homepage = 'https://github.com/himotoyoshi/carray-io-sqlite3'
|
20
|
+
s.files = files
|
21
|
+
# s.extensions = [ "ext/extconf.rb" ]
|
22
|
+
s.required_ruby_version = ">= 1.8.1"
|
23
|
+
s.add_runtime_dependency 'carray', '~> 1.3'
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require "carray/io/table"
|
2
|
+
|
3
|
+
class CArray
|
4
|
+
|
5
|
+
def self.load_sqlite3 (expr, *args)
|
6
|
+
case expr
|
7
|
+
when String
|
8
|
+
file = expr
|
9
|
+
sql, *vars = *args
|
10
|
+
db = SQLite3::Database.new(file)
|
11
|
+
names, *table = db.execute2(sql, *vars)
|
12
|
+
db.close
|
13
|
+
when SQLite3::Database
|
14
|
+
db = expr
|
15
|
+
sql, *vars = *args
|
16
|
+
names, *table = db.execute2(sql, *vars)
|
17
|
+
when SQLite3::Statement
|
18
|
+
stmt = expr
|
19
|
+
vars = args
|
20
|
+
names = stmt.columns
|
21
|
+
table = stmt.execute!(*vars)
|
22
|
+
else
|
23
|
+
raise "invalid 1st arg"
|
24
|
+
end
|
25
|
+
table = table.to_ca
|
26
|
+
table.extend(CA::TableMethods)
|
27
|
+
table.column_names = names
|
28
|
+
return table
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_sqlite3 (database: nil, table:, datatype: "numeric", schema: nil, transaction: true)
|
32
|
+
unless rank <= 2
|
33
|
+
raise "to_sqlite3 is valid only for 2-dim array (table)"
|
34
|
+
end
|
35
|
+
case database
|
36
|
+
when SQLite3::Database
|
37
|
+
when String
|
38
|
+
if File.exist? database
|
39
|
+
database = SQLite3::Database.open(database)
|
40
|
+
else
|
41
|
+
database = SQLite3::Database.new(database)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
database = SQLite3::Database.new ":memory:"
|
45
|
+
end
|
46
|
+
if respond_to?(:column_names) and column_names
|
47
|
+
vars = column_names
|
48
|
+
else
|
49
|
+
if rank == 1
|
50
|
+
vars = ["c0"]
|
51
|
+
else
|
52
|
+
vars = CArray.object(dim1).seq.map{|s| "c#{s}" }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if schema
|
57
|
+
database.execute "create table if not exists #{table} (" + schema + ")"
|
58
|
+
else
|
59
|
+
database.execute "create table if not exists #{table} (" + vars.map{|s| s + " " + datatype }.join(",") + ")"
|
60
|
+
end
|
61
|
+
|
62
|
+
insert = database.prepare %{ insert or replace into #{table} values (#{(["?"]*vars.size).join(",")}) }
|
63
|
+
database.transaction if transaction
|
64
|
+
if rank == 1
|
65
|
+
dim0.times do |i|
|
66
|
+
insert.execute [self[i]]
|
67
|
+
end
|
68
|
+
else
|
69
|
+
begin
|
70
|
+
dim0.times do |i|
|
71
|
+
begin
|
72
|
+
insert.execute self[i,nil].to_a
|
73
|
+
rescue
|
74
|
+
puts self[i,nil].to_a
|
75
|
+
raise $!
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
database.commit if transaction
|
81
|
+
insert.close
|
82
|
+
return database
|
83
|
+
end
|
84
|
+
|
85
|
+
def unblob (type, subdim = nil)
|
86
|
+
bytes = CArray.sizeof(type)
|
87
|
+
elem = nil
|
88
|
+
self.each do |e|
|
89
|
+
unless e.nil?
|
90
|
+
elem = e
|
91
|
+
break
|
92
|
+
end
|
93
|
+
end
|
94
|
+
if elem == nil and subdim == nil
|
95
|
+
raise "all element is nil, please specify dimension."
|
96
|
+
end
|
97
|
+
unless subdim
|
98
|
+
subdim = [elem.bytesize/bytes]
|
99
|
+
end
|
100
|
+
out = CArray.new(type, dim + subdim)
|
101
|
+
needed_bytes = out.elements/self.elements*bytes
|
102
|
+
ref = out.refer(:fixlen, dim, :bytes=>needed_bytes)
|
103
|
+
if elem and needed_bytes != elem.bytesize
|
104
|
+
self.each_addr do |addr|
|
105
|
+
if self[addr].nil?
|
106
|
+
ref[[addr]] = UNDEF
|
107
|
+
else
|
108
|
+
ref[[addr]].load_binary self[addr]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
elsif self.any_equal?(nil)
|
112
|
+
copy = self.to_ca
|
113
|
+
sel = self.eq(nil)
|
114
|
+
copy[sel] = "\0" * needed_bytes
|
115
|
+
ref.load_binary copy.join
|
116
|
+
ref[sel] = UNDEF
|
117
|
+
else
|
118
|
+
ref.load_binary self.join
|
119
|
+
end
|
120
|
+
return out
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
module SQLite3
|
126
|
+
|
127
|
+
class Database
|
128
|
+
|
129
|
+
def create_table (table, data, names = nil)
|
130
|
+
ncols = data.rank == 1 ? 1 : data.dim1
|
131
|
+
if names
|
132
|
+
varlist = names.map{|s| s.to_s }
|
133
|
+
elsif data.respond_to?(:names)
|
134
|
+
varlist = data.names
|
135
|
+
else
|
136
|
+
varlist = []
|
137
|
+
ncols.times do |i|
|
138
|
+
varlist << "col#{i}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
execute %{create table #{table} (#{varlist.join(",")})}
|
142
|
+
insert(table, data)
|
143
|
+
end
|
144
|
+
|
145
|
+
def insert (table, data)
|
146
|
+
table_info = execute %{
|
147
|
+
pragma table_info(#{table})
|
148
|
+
}
|
149
|
+
if table_info.empty?
|
150
|
+
raise "#{table} is empty table"
|
151
|
+
end
|
152
|
+
qstns = (["?"]*table_info.size).join(",")
|
153
|
+
self.transaction {
|
154
|
+
stmt = prepare %{
|
155
|
+
insert or replace into #{table} values (#{qstns})
|
156
|
+
}
|
157
|
+
data.to_a.each do |row|
|
158
|
+
stmt.execute *row
|
159
|
+
end
|
160
|
+
stmt.close
|
161
|
+
}
|
162
|
+
end
|
163
|
+
|
164
|
+
def schema (table = nil)
|
165
|
+
if table
|
166
|
+
return get_first_value %{
|
167
|
+
select sql from sqlite_master where type in ('table', 'view', 'index') and name = "#{table}"
|
168
|
+
}
|
169
|
+
else
|
170
|
+
return execute(%{
|
171
|
+
select sql from sqlite_master where type in ('table', 'view', 'index')
|
172
|
+
}).map{|v| v[0]}
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# insert
|
177
|
+
def import_table (dbfile, src_table, dst_table = nil)
|
178
|
+
dst_table ||= src_table
|
179
|
+
db = "db#{Thread.current.object_id}"
|
180
|
+
execute %{
|
181
|
+
attach database "#{dbfile}" as #{db};
|
182
|
+
}
|
183
|
+
sql = get_first_value %{
|
184
|
+
select sql from #{db}.sqlite_master where type = 'table' and name = "#{src_table}"
|
185
|
+
}
|
186
|
+
sql.sub!(/create\s+table\s(.+?)\s/i, "create table if not exists #{dst_table}")
|
187
|
+
execute sql
|
188
|
+
execute %{
|
189
|
+
insert into #{dst_table} select * from #{db}.#{src_table};
|
190
|
+
}
|
191
|
+
indeces = execute %{
|
192
|
+
select sql from #{db}.sqlite_master where type = 'index' and tbl_name = "#{src_table}"
|
193
|
+
}
|
194
|
+
indeces.each do |row|
|
195
|
+
sql = row[0]
|
196
|
+
unless sql
|
197
|
+
break
|
198
|
+
end
|
199
|
+
sql.sub!(/create\s+index/i, "create index if not exists")
|
200
|
+
sql.sub!(/on\s+#{src_table}\(/i, "on #{dst_table}(")
|
201
|
+
execute sql
|
202
|
+
end
|
203
|
+
execute %{
|
204
|
+
detach database #{db};
|
205
|
+
}
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: carray-io-sqlite3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hiroki Motoyoshi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-06-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: carray
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
description: " SQLite3 interface for CArray\n"
|
28
|
+
email: ''
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- Rakefile
|
34
|
+
- carray-io-sqlite3.gemspec
|
35
|
+
- lib/carray-io-sqlite3.rb
|
36
|
+
- lib/carray-io-sqlite3/core.rb
|
37
|
+
homepage: https://github.com/himotoyoshi/carray-io-sqlite3
|
38
|
+
licenses:
|
39
|
+
- MIT
|
40
|
+
metadata: {}
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 1.8.1
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 2.7.7
|
58
|
+
signing_key:
|
59
|
+
specification_version: 4
|
60
|
+
summary: SQLite3 interface for CArray
|
61
|
+
test_files: []
|