ydbd-pg 0.5.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.
- checksums.yaml +7 -0
- data/ChangeLog +3703 -0
- data/LICENSE +25 -0
- data/lib/dbd/Pg.rb +188 -0
- data/lib/dbd/pg/database.rb +516 -0
- data/lib/dbd/pg/exec.rb +47 -0
- data/lib/dbd/pg/statement.rb +160 -0
- data/lib/dbd/pg/tuples.rb +121 -0
- data/lib/dbd/pg/type.rb +209 -0
- data/readme.md +274 -0
- data/test/DBD_TESTS +50 -0
- data/test/dbd/general/test_database.rb +206 -0
- data/test/dbd/general/test_statement.rb +326 -0
- data/test/dbd/general/test_types.rb +296 -0
- data/test/dbd/postgresql/base.rb +31 -0
- data/test/dbd/postgresql/down.sql +31 -0
- data/test/dbd/postgresql/test_arrays.rb +179 -0
- data/test/dbd/postgresql/test_async.rb +121 -0
- data/test/dbd/postgresql/test_blob.rb +36 -0
- data/test/dbd/postgresql/test_bytea.rb +87 -0
- data/test/dbd/postgresql/test_ping.rb +10 -0
- data/test/dbd/postgresql/test_timestamp.rb +77 -0
- data/test/dbd/postgresql/test_transactions.rb +58 -0
- data/test/dbd/postgresql/testdbipg.rb +307 -0
- data/test/dbd/postgresql/up.sql +60 -0
- data/test/ts_dbd.rb +131 -0
- metadata +100 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
DBDConfig.set_testbase(:postgresql, Class.new(Test::Unit::TestCase) do
|
4
|
+
|
5
|
+
def dbtype
|
6
|
+
"postgresql"
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_base
|
10
|
+
assert_equal(@dbh.driver_name, "Pg")
|
11
|
+
assert_kind_of(DBI::DBD::Pg::Database, @dbh.instance_variable_get(:@handle))
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_base_dbh
|
15
|
+
config = DBDConfig.get_config['postgresql']
|
16
|
+
@dbh = DBI.connect("dbi:Pg:#{config['dbname']}", config['username'], config['password'])
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
set_base_dbh
|
21
|
+
DBDConfig.inject_sql(@dbh, dbtype, "dbd/postgresql/up.sql")
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
@sth.finish if @sth && !@sth.finished?
|
26
|
+
config = DBDConfig.get_config['postgresql']
|
27
|
+
DBDConfig.inject_sql(@dbh, dbtype, "dbd/postgresql/down.sql")
|
28
|
+
@dbh.disconnect
|
29
|
+
end
|
30
|
+
end
|
31
|
+
)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
drop view view_names;
|
2
|
+
---
|
3
|
+
drop table names;
|
4
|
+
---
|
5
|
+
drop table blob_test;
|
6
|
+
---
|
7
|
+
drop table boolean_test;
|
8
|
+
---
|
9
|
+
drop table time_test;
|
10
|
+
---
|
11
|
+
drop table timestamp_test;
|
12
|
+
---
|
13
|
+
drop table bit_test;
|
14
|
+
---
|
15
|
+
drop table field_types_test;
|
16
|
+
---
|
17
|
+
drop table db_specific_types_test;
|
18
|
+
---
|
19
|
+
drop table array_test;
|
20
|
+
---
|
21
|
+
drop table bytea_test;
|
22
|
+
---
|
23
|
+
drop table precision_test;
|
24
|
+
---
|
25
|
+
drop table enum_type_test;
|
26
|
+
---
|
27
|
+
drop type enum_test;
|
28
|
+
---
|
29
|
+
drop schema schema1 cascade;
|
30
|
+
---
|
31
|
+
drop schema schema2 cascade;
|
@@ -0,0 +1,179 @@
|
|
1
|
+
class TestPostgresArray < DBDConfig.testbase(:postgresql)
|
2
|
+
def test_array_type
|
3
|
+
assert_nothing_raised do
|
4
|
+
cols = @dbh.columns("array_test")
|
5
|
+
assert_equal(
|
6
|
+
[
|
7
|
+
{
|
8
|
+
:name =>"foo",
|
9
|
+
:default =>nil,
|
10
|
+
:primary =>nil,
|
11
|
+
:scale =>nil,
|
12
|
+
:sql_type =>DBI::SQL_INTEGER,
|
13
|
+
:nullable =>true,
|
14
|
+
:indexed =>false,
|
15
|
+
:precision =>-1,
|
16
|
+
:type_name =>"integer",
|
17
|
+
:unique =>nil,
|
18
|
+
:array_of_type => true
|
19
|
+
},
|
20
|
+
{
|
21
|
+
:name =>"bar",
|
22
|
+
:default =>nil,
|
23
|
+
:primary =>nil,
|
24
|
+
:scale =>nil,
|
25
|
+
:sql_type =>DBI::SQL_INTEGER,
|
26
|
+
:nullable =>true,
|
27
|
+
:indexed =>false,
|
28
|
+
:precision =>-1,
|
29
|
+
:type_name =>"integer",
|
30
|
+
:unique =>nil,
|
31
|
+
:array_of_type => true
|
32
|
+
},
|
33
|
+
{
|
34
|
+
:name =>"baz",
|
35
|
+
:default =>nil,
|
36
|
+
:primary =>nil,
|
37
|
+
:scale =>nil,
|
38
|
+
:sql_type =>DBI::SQL_INTEGER,
|
39
|
+
:nullable =>true,
|
40
|
+
:indexed =>false,
|
41
|
+
:precision =>-1,
|
42
|
+
:type_name =>"integer",
|
43
|
+
:unique =>nil,
|
44
|
+
:array_of_type => true
|
45
|
+
},
|
46
|
+
{
|
47
|
+
:array_of_type=>true,
|
48
|
+
:unique=>nil,
|
49
|
+
:precision=>-1,
|
50
|
+
:name=>"quux",
|
51
|
+
:default=>nil,
|
52
|
+
:indexed=>false,
|
53
|
+
:scale=>nil,
|
54
|
+
:primary=>nil,
|
55
|
+
:sql_type=>12,
|
56
|
+
:nullable=>true,
|
57
|
+
:type_name=>"character varying"
|
58
|
+
}
|
59
|
+
], cols.collect { |x| x.reject { |key, value| key == :dbi_type } }
|
60
|
+
)
|
61
|
+
|
62
|
+
assert_equal(([DBI::DBD::Pg::Type::Array] * 4), cols.collect { |x| x["dbi_type"].class })
|
63
|
+
assert_equal((([DBI::Type::Integer] * 3) + [DBI::Type::Varchar]), cols.collect { |x| x["dbi_type"].base_type })
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_array_parser
|
68
|
+
# string representation
|
69
|
+
assert_nothing_raised do
|
70
|
+
sth = @dbh.prepare('insert into array_test (foo) values (?)')
|
71
|
+
sth.execute('{1,2,3}')
|
72
|
+
sth.finish
|
73
|
+
end
|
74
|
+
|
75
|
+
assert_nothing_raised do
|
76
|
+
sth = @dbh.prepare('insert into array_test (foo) values (?)')
|
77
|
+
sth.execute([1,2,3])
|
78
|
+
sth.finish
|
79
|
+
end
|
80
|
+
|
81
|
+
assert_nothing_raised do
|
82
|
+
sth = @dbh.prepare('insert into array_test (quux) values (?)')
|
83
|
+
sth.execute(["Hello\\ World", "Again\\"])
|
84
|
+
sth.finish
|
85
|
+
end
|
86
|
+
|
87
|
+
assert_nothing_raised do
|
88
|
+
sth = @dbh.prepare('select foo from array_test where foo is not null')
|
89
|
+
sth.execute
|
90
|
+
assert_equal(
|
91
|
+
[
|
92
|
+
[[1,2,3]],
|
93
|
+
[[1,2,3]],
|
94
|
+
], sth.fetch_all
|
95
|
+
)
|
96
|
+
sth.finish
|
97
|
+
|
98
|
+
sth = @dbh.prepare('select quux from array_test where quux is not null')
|
99
|
+
sth.execute
|
100
|
+
|
101
|
+
assert_equal(
|
102
|
+
[
|
103
|
+
[["Hello\\ World", "Again\\"]]
|
104
|
+
], sth.fetch_all
|
105
|
+
)
|
106
|
+
|
107
|
+
sth.finish
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_array_boundaries
|
112
|
+
# bar has a max extents of 3
|
113
|
+
sth = @dbh.prepare('insert into array_test (bar) values (?)')
|
114
|
+
|
115
|
+
assert_nothing_raised do
|
116
|
+
sth.execute('{1,2,3}')
|
117
|
+
end
|
118
|
+
|
119
|
+
# XXX postgresql does not enforce extents on single-dimension arrays
|
120
|
+
assert_nothing_raised do
|
121
|
+
sth.execute('{1,2,3,4}')
|
122
|
+
end
|
123
|
+
|
124
|
+
sth.finish
|
125
|
+
sth = @dbh.prepare('insert into array_test(baz) values (?)')
|
126
|
+
|
127
|
+
assert_nothing_raised do
|
128
|
+
sth.execute('{{1,2,3}, {1,2,3}}')
|
129
|
+
end
|
130
|
+
|
131
|
+
assert_nothing_raised do
|
132
|
+
# XXX for the record, I have no fucking idea why this works, what
|
133
|
+
# it's technically represented as and what backwards array
|
134
|
+
# implementation would allow it to work.
|
135
|
+
#
|
136
|
+
# I'm hoping it'll break on some future version of postgresql so I
|
137
|
+
# can fix it.
|
138
|
+
sth.execute('{1,2,3}')
|
139
|
+
end
|
140
|
+
|
141
|
+
assert_raises(DBI::ProgrammingError) do
|
142
|
+
sth.execute('{{1,2,3,4}, {1,2,3}}')
|
143
|
+
end
|
144
|
+
|
145
|
+
assert_raises(DBI::ProgrammingError) do
|
146
|
+
sth.execute('{{1,2,3}, {1,2,3,4}}')
|
147
|
+
end
|
148
|
+
|
149
|
+
sth.finish
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_array_type_parser
|
153
|
+
pc = DBI::DBD::Pg::Type::Array
|
154
|
+
|
155
|
+
assert_nothing_raised do
|
156
|
+
po = pc.new(DBI::Type::Integer)
|
157
|
+
assert_equal([1,2,3], po.parse("{1,2,3}"))
|
158
|
+
assert_equal([[1,2,3],[4,5,6]], po.parse("{{1,2,3},{4,5,6}}"))
|
159
|
+
end
|
160
|
+
|
161
|
+
assert_nothing_raised do
|
162
|
+
po = pc.new(DBI::Type::Varchar)
|
163
|
+
assert_equal(["one", "two", "three"], po.parse("{\"one\",\"two\",\"three\"}"))
|
164
|
+
assert_equal([["one"], ["two\\"]], po.parse("{{\"one\"},{\"two\\\\\"}}"))
|
165
|
+
assert_equal([["one", "two\\"], ["three\\", "four"]], po.parse("{{\"one\",\"two\\\\\"},{\"three\\\\\",\"four\"}}"))
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_array_generator
|
170
|
+
pg = DBI::DBD::Pg
|
171
|
+
|
172
|
+
assert_nothing_raised do
|
173
|
+
assert_equal("{1,2,3}", pg.generate_array([1,2,3]))
|
174
|
+
assert_equal("{{1,2,3},{1,2,3}}", pg.generate_array([[1,2,3],[1,2,3]]))
|
175
|
+
assert_equal("{\"one\",\"two\"}", pg.generate_array(["one", "two"]))
|
176
|
+
assert_equal("{\"hello\\\\ world\",\"again\"}", pg.generate_array(["hello\\ world", "again"]))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
class TestPostgresAsync < DBDConfig.testbase(:postgresql)
|
2
|
+
def get_dbh
|
3
|
+
config = DBDConfig.get_config['postgresql']
|
4
|
+
DBI.connect("dbi:Pg:#{config['dbname']}", config['username'], config['password'])
|
5
|
+
end
|
6
|
+
|
7
|
+
def get_db_info
|
8
|
+
config = DBDConfig.get_config['postgresql']
|
9
|
+
dsn = "dbi:Pg:database=#{config['dbname']}"
|
10
|
+
user = config['username']
|
11
|
+
pass = config['password']
|
12
|
+
|
13
|
+
return [dsn, user, pass]
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_async_default
|
17
|
+
dsn, user, pass = get_db_info
|
18
|
+
|
19
|
+
DBI.connect(dsn, user, pass) do |dbh|
|
20
|
+
assert_equal false, dbh['pg_async']
|
21
|
+
assert_equal false, dbh['NonBlocking']
|
22
|
+
dbh.prepare('SELECT 1') do |sth| # Statement inherits
|
23
|
+
assert_equal false, sth['pg_async']
|
24
|
+
assert_equal false, sth['NonBlocking']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_async_dsn_enable
|
30
|
+
dsn, user, pass = get_db_info
|
31
|
+
|
32
|
+
for enable in ['true', 'TRUE', 'tRuE']
|
33
|
+
DBI.connect(dsn + ";pg_async=#{enable}", user, pass) do |dbh|
|
34
|
+
assert_equal true, dbh['pg_async']
|
35
|
+
assert_equal true, dbh['NonBlocking']
|
36
|
+
dbh.prepare('SELECT 1') do |sth| # Statement inherits
|
37
|
+
assert_equal true, sth['pg_async']
|
38
|
+
assert_equal true, sth['NonBlocking']
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_async_attr_enable
|
45
|
+
dsn, user, pass = get_db_info
|
46
|
+
|
47
|
+
for enable in ['true', 'TRUE', 'tRuE']
|
48
|
+
DBI.connect(dsn, user, pass, { 'pg_async' => enable } ) do |dbh|
|
49
|
+
assert_equal true, dbh['pg_async']
|
50
|
+
assert_equal true, dbh['NonBlocking']
|
51
|
+
dbh.prepare('SELECT 1') do |sth| # Statement inherits
|
52
|
+
assert_equal true, sth['pg_async']
|
53
|
+
assert_equal true, sth['NonBlocking']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_async_dsn_disable
|
60
|
+
dsn, user, pass = get_db_info
|
61
|
+
|
62
|
+
for disable in ['false', 'FALSE', 'fAlSe']
|
63
|
+
DBI.connect(dsn + ";pg_async=#{disable}", user, pass) do |dbh|
|
64
|
+
assert_equal false, dbh['pg_async']
|
65
|
+
assert_equal false, dbh['NonBlocking']
|
66
|
+
dbh.prepare('SELECT 1') do |sth| # Statement inherits
|
67
|
+
assert_equal false, sth['pg_async']
|
68
|
+
assert_equal false, sth['NonBlocking']
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_async_attr_disable
|
75
|
+
dsn, user, pass = get_db_info
|
76
|
+
|
77
|
+
for disable in ['false', 'FALSE', 'fAlSe']
|
78
|
+
DBI.connect(dsn, user, pass, { 'pg_async' => disable }) do |dbh|
|
79
|
+
assert_equal false, dbh['pg_async']
|
80
|
+
assert_equal false, dbh['NonBlocking']
|
81
|
+
dbh.prepare('SELECT 1') do |sth| # Statement inherits
|
82
|
+
assert_equal false, sth['pg_async']
|
83
|
+
assert_equal false, sth['NonBlocking']
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_manual_enable
|
90
|
+
dsn, user, pass = get_db_info
|
91
|
+
|
92
|
+
DBI.connect(dsn, user, pass) do |dbh|
|
93
|
+
dbh['pg_async'] = true
|
94
|
+
assert_equal true, dbh['pg_async']
|
95
|
+
assert_equal true, dbh['NonBlocking']
|
96
|
+
dbh.prepare('SELECT 1') do |sth| # Statement inherits
|
97
|
+
assert_equal true, sth['pg_async']
|
98
|
+
assert_equal true, sth['NonBlocking']
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_async_commands
|
104
|
+
dsn, user, pass = get_db_info
|
105
|
+
|
106
|
+
DBI.connect(dsn + ";pg_async=true", user, pass) do |dbh|
|
107
|
+
assert_equal true, dbh['pg_async']
|
108
|
+
assert_equal true, dbh['NonBlocking']
|
109
|
+
ret = dbh.select_all('SELECT 1')
|
110
|
+
assert_equal [[1]], ret
|
111
|
+
|
112
|
+
ret = dbh.select_all(%q{SELECT 1 WHERE 'foo' = ?}, 'bar')
|
113
|
+
assert_equal [], ret
|
114
|
+
|
115
|
+
dbh.prepare(%q{SELECT 1 WHERE 'foo' = ?}) do |sth|
|
116
|
+
sth.execute('bar')
|
117
|
+
assert_equal [], sth.fetch_all
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class TestPostgresBlob < DBDConfig.testbase(:postgresql)
|
2
|
+
DATA = "this is my new binary object"
|
3
|
+
|
4
|
+
def test_insert
|
5
|
+
assert @dbh
|
6
|
+
assert @dbh.ping
|
7
|
+
|
8
|
+
# test with DBI::Binary
|
9
|
+
assert_equal 1, @dbh.do("INSERT INTO blob_test (name, data) VALUES (?,?)", "test", DBI::Binary.new(DATA))
|
10
|
+
|
11
|
+
# test with blob_create directly
|
12
|
+
blob = @dbh.func(:blob_create, PGconn::INV_WRITE)
|
13
|
+
assert blob
|
14
|
+
assert @dbh.func(:blob_write, blob, DATA)
|
15
|
+
assert_equal 1, @dbh.do("INSERT INTO blob_test (name, data) VALUES (?,?)", "test (2)", blob)
|
16
|
+
|
17
|
+
# test with blob_import directly
|
18
|
+
File.open('/tmp/pg_dbi_import_test', 'w') { |f| f << DATA }
|
19
|
+
blob = @dbh.func(:blob_import, '/tmp/pg_dbi_import_test')
|
20
|
+
assert blob
|
21
|
+
assert_equal 1, @dbh.do("INSERT INTO blob_test (name, data) VALUES (?,?)", "test (2)", blob)
|
22
|
+
|
23
|
+
index = 0
|
24
|
+
@dbh.select_all("SELECT name, data FROM blob_test") do |name, data|
|
25
|
+
index += 1
|
26
|
+
assert_equal DATA, @dbh.func(:blob_read, data, DATA.length)
|
27
|
+
@dbh.func(:blob_export, data, '/tmp/pg_dbi_read_test')
|
28
|
+
assert_equal DATA, File.read('/tmp/pg_dbi_read_test')
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_equal 3, index
|
32
|
+
|
33
|
+
File.unlink("/tmp/pg_dbi_read_test")
|
34
|
+
File.unlink("/tmp/pg_dbi_import_test")
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'dbd/Pg'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rubygems'
|
5
|
+
gem 'pg'
|
6
|
+
rescue Exception => e
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'pg'
|
10
|
+
|
11
|
+
LEN = 50
|
12
|
+
|
13
|
+
class TestPostgresByteA < DBDConfig.testbase(:postgresql)
|
14
|
+
# FIXME the 'pg' module is broken and doesn't encode/decode properly.
|
15
|
+
# this test should prove that the 'pg' module works so we can back out our
|
16
|
+
# hacks.
|
17
|
+
def skip_underlying_driver
|
18
|
+
str = generate_random_string
|
19
|
+
|
20
|
+
encoded = PGconn.escape_bytea(str.dup)
|
21
|
+
decoded = PGconn.unescape_bytea(encoded)
|
22
|
+
|
23
|
+
assert_equal str, decoded
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_encode_decode
|
27
|
+
bytea = DBI::DBD::Pg::Type::ByteA
|
28
|
+
|
29
|
+
# some specific cases that were failing intermittenly
|
30
|
+
# poor \\ handling
|
31
|
+
str = "\236\000\257\202G<\371\035TPEO\211\005*AH'H\3136\360\004\245\261\037\340u\003s\\772X\231\002\200\n\327\202\217\353\177r\317o\341\237\341"
|
32
|
+
encoded = bytea.escape_bytea(str)
|
33
|
+
decoded = bytea.parse(encoded)
|
34
|
+
|
35
|
+
assert_equal str, decoded
|
36
|
+
|
37
|
+
# the split hack not working
|
38
|
+
str = "\343\336e\260\337\373\314\026\323#\237i\035\0302\024\346X\274\016\324\371\206\036\230\374\206#rA\n\214\272\316\330\025\374\000\2663\244M\255x\360\002\266q\336\231"
|
39
|
+
|
40
|
+
encoded = bytea.escape_bytea(str)
|
41
|
+
decoded = bytea.parse(encoded)
|
42
|
+
|
43
|
+
assert_equal str, decoded
|
44
|
+
|
45
|
+
# delimiter at the end
|
46
|
+
str = "\343\336e\260\337\373\314\026\323#\237i\035\0302\024\346X\274\016\324\371\206\036\230\374\206#rA\n\214\272\316\330\025\374\000\2663\244M\255x\360\002\266q\336\231\\\\\\\\"
|
47
|
+
|
48
|
+
encoded = bytea.escape_bytea(str)
|
49
|
+
decoded = bytea.parse(encoded)
|
50
|
+
|
51
|
+
assert_equal str, decoded
|
52
|
+
|
53
|
+
# a huge test to weed out all the stragglers
|
54
|
+
5_000.times do
|
55
|
+
str = generate_random_string
|
56
|
+
|
57
|
+
encoded = bytea.escape_bytea(str)
|
58
|
+
decoded = bytea.parse(encoded)
|
59
|
+
|
60
|
+
assert_equal str, decoded
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_insert_retrieve
|
65
|
+
assert_nothing_raised do
|
66
|
+
str = generate_random_string
|
67
|
+
sth = @dbh.prepare('insert into bytea_test (foo) values (?)')
|
68
|
+
sth.execute(DBI::DBD::Pg::Type::ByteA.new(str))
|
69
|
+
sth.finish
|
70
|
+
|
71
|
+
sth = @dbh.prepare('select * from bytea_test')
|
72
|
+
sth.execute
|
73
|
+
assert_equal([str], sth.fetch)
|
74
|
+
sth.finish
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def generate_random_string
|
79
|
+
# random string test
|
80
|
+
str = " " * LEN
|
81
|
+
for i in 0...LEN
|
82
|
+
str[i] = (rand * 256).to_i.chr
|
83
|
+
end
|
84
|
+
|
85
|
+
return str
|
86
|
+
end
|
87
|
+
end
|