Skip to content

Commit bc02b5d

Browse files
authored
Merge pull request #590 from andyundso/typed-data
Use `TypedData` and CI-related fixes
2 parents 5baa708 + 3992255 commit bc02b5d

File tree

10 files changed

+116
-84
lines changed

10 files changed

+116
-84
lines changed

.github/workflows/ci.yml

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,12 @@ jobs:
292292
fail-fast: false
293293
matrix:
294294
ruby-version:
295-
- "2.7"
296-
- "3.0"
297-
- "3.1"
295+
# currently fails with a dependency resolution
296+
# looking for conflicting packages...
297+
# :: installing mingw-w64-x86_64-gcc-libs (15.1.0-8) breaks dependency 'mingw-w64-x86_64-gcc-libs=14.2.0-3' required by mingw-w64-x86_64-gcc
298+
# - "2.7"
299+
# - "3.0"
300+
# - "3.1"
298301
- "3.2"
299302
- "3.3"
300303
- "3.4"
@@ -570,11 +573,11 @@ jobs:
570573
shell: bash
571574
run: bundle exec standardrb
572575

573-
- name: Check artistic style
574-
uses: per1234/artistic-style-action@v1
575-
with:
576-
options-file-path: "astyle.conf"
577-
target-paths: "./ext/"
578-
name-patterns: |
579-
- '*.c'
580-
- '*.h'
576+
# - name: Check artistic style
577+
# uses: per1234/artistic-style-action@v1
578+
# with:
579+
# options-file-path: "astyle.conf"
580+
# target-paths: "./ext/"
581+
# name-patterns: |
582+
# - '*.c'
583+
# - '*.h'

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## (unreleased)
22

33
* Use freetds v1.5.1 and OpenSSL v3.5.0 for Windows and Linux builds.
4+
* Use `TypedData` in C-Land.
45

56
## 3.2.1
67

ext/tiny_tds/client.c

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,54 @@ static ID intern_source_eql, intern_severity_eql, intern_db_error_number_eql, in
88
static ID intern_new, intern_dup, intern_transpose_iconv_encoding, intern_local_offset, intern_gsub, intern_call;
99
VALUE opt_escape_regex, opt_escape_dblquote;
1010

11+
static void rb_tinytds_client_mark(void *ptr)
12+
{
13+
tinytds_client_wrapper *cwrap = (tinytds_client_wrapper *)ptr;
14+
15+
if (cwrap) {
16+
rb_gc_mark(cwrap->charset);
17+
}
18+
}
19+
20+
static void rb_tinytds_client_free(void *ptr)
21+
{
22+
tinytds_client_wrapper *cwrap = (tinytds_client_wrapper *)ptr;
23+
24+
if (cwrap->login) {
25+
dbloginfree(cwrap->login);
26+
}
27+
28+
if (cwrap->client && !cwrap->closed) {
29+
dbclose(cwrap->client);
30+
cwrap->client = NULL;
31+
cwrap->closed = 1;
32+
cwrap->userdata->closed = 1;
33+
}
34+
35+
xfree(cwrap->userdata);
36+
xfree(ptr);
37+
}
38+
39+
static size_t tinytds_client_wrapper_size(const void* data)
40+
{
41+
return sizeof(tinytds_client_wrapper);
42+
}
43+
44+
static const rb_data_type_t tinytds_client_wrapper_type = {
45+
.wrap_struct_name = "tinytds_client_wrapper",
46+
.function = {
47+
.dmark = rb_tinytds_client_mark,
48+
.dfree = rb_tinytds_client_free,
49+
.dsize = tinytds_client_wrapper_size,
50+
},
51+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
52+
};
1153

1254
// Lib Macros
1355

1456
#define GET_CLIENT_WRAPPER(self) \
1557
tinytds_client_wrapper *cwrap; \
16-
Data_Get_Struct(self, tinytds_client_wrapper, cwrap)
58+
TypedData_Get_Struct(self, tinytds_client_wrapper, &tinytds_client_wrapper_type, cwrap)
1759

1860
#define REQUIRE_OPEN_CLIENT(cwrap) \
1961
if (cwrap->closed || cwrap->userdata->closed) { \
@@ -244,39 +286,11 @@ static void rb_tinytds_client_reset_userdata(tinytds_client_userdata *userdata)
244286
userdata->nonblocking_errors_size = 0;
245287
}
246288

247-
static void rb_tinytds_client_mark(void *ptr)
248-
{
249-
tinytds_client_wrapper *cwrap = (tinytds_client_wrapper *)ptr;
250-
251-
if (cwrap) {
252-
rb_gc_mark(cwrap->charset);
253-
}
254-
}
255-
256-
static void rb_tinytds_client_free(void *ptr)
257-
{
258-
tinytds_client_wrapper *cwrap = (tinytds_client_wrapper *)ptr;
259-
260-
if (cwrap->login) {
261-
dbloginfree(cwrap->login);
262-
}
263-
264-
if (cwrap->client && !cwrap->closed) {
265-
dbclose(cwrap->client);
266-
cwrap->client = NULL;
267-
cwrap->closed = 1;
268-
cwrap->userdata->closed = 1;
269-
}
270-
271-
xfree(cwrap->userdata);
272-
xfree(ptr);
273-
}
274-
275289
static VALUE allocate(VALUE klass)
276290
{
277291
VALUE obj;
278292
tinytds_client_wrapper *cwrap;
279-
obj = Data_Make_Struct(klass, tinytds_client_wrapper, rb_tinytds_client_mark, rb_tinytds_client_free, cwrap);
293+
obj = TypedData_Make_Struct(klass, tinytds_client_wrapper, &tinytds_client_wrapper_type, cwrap);
280294
cwrap->closed = 1;
281295
cwrap->charset = Qnil;
282296
cwrap->userdata = malloc(sizeof(tinytds_client_userdata));

ext/tiny_tds/result.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ rb_encoding *binaryEncoding;
3535

3636

3737
// Lib Backend (Memory Management)
38-
3938
static void rb_tinytds_result_mark(void *ptr)
4039
{
4140
tinytds_result_wrapper *rwrap = (tinytds_result_wrapper *)ptr;
@@ -54,11 +53,26 @@ static void rb_tinytds_result_free(void *ptr)
5453
xfree(ptr);
5554
}
5655

56+
static size_t tinytds_result_wrapper_size(const void* data)
57+
{
58+
return sizeof(tinytds_result_wrapper);
59+
}
60+
61+
const rb_data_type_t tinytds_result_wrapper_type = {
62+
.wrap_struct_name = "tinytds_result_wrapper",
63+
.function = {
64+
.dmark = rb_tinytds_result_mark,
65+
.dfree = rb_tinytds_result_free,
66+
.dsize = tinytds_result_wrapper_size,
67+
},
68+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
69+
};
70+
5771
VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap)
5872
{
5973
VALUE obj;
6074
tinytds_result_wrapper *rwrap;
61-
obj = Data_Make_Struct(cTinyTdsResult, tinytds_result_wrapper, rb_tinytds_result_mark, rb_tinytds_result_free, rwrap);
75+
obj = TypedData_Make_Struct(cTinyTdsResult, tinytds_result_wrapper, &tinytds_result_wrapper_type, rwrap);
6276
rwrap->cwrap = cwrap;
6377
rwrap->client = cwrap->client;
6478
rwrap->local_offset = Qnil;

ext/tiny_tds/result.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ typedef struct {
1919
unsigned long number_of_rows;
2020
} tinytds_result_wrapper;
2121

22+
extern const rb_data_type_t tinytds_result_wrapper_type;
2223

2324
// Lib Macros
24-
2525
#define GET_RESULT_WRAPPER(self) \
2626
tinytds_result_wrapper *rwrap; \
27-
Data_Get_Struct(self, tinytds_result_wrapper, rwrap)
27+
TypedData_Get_Struct(self, tinytds_result_wrapper, &tinytds_result_wrapper_type, rwrap)
2828

2929

3030

lib/tiny_tds.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
module TinyTds
1111
# Is this file part of a fat binary gem with bundled freetds?
1212
# This path must be enabled by add_dll_directory on Windows.
13-
gplat = ::Gem::Platform.local
14-
FREETDS_LIB_PATH = Dir[File.expand_path("../ports/#{gplat.cpu}-#{gplat.os}*/{bin,lib}", __dir__)].first
13+
FREETDS_LIB_PATH = TinyTds::Gem.ports_bin_and_lib_paths.first
1514

1615
add_dll_path = proc do |path, &block|
1716
if RUBY_PLATFORM =~ /(mswin|mingw)/i && path

lib/tiny_tds/bin.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def with_ports_paths
5050

5151
begin
5252
ENV["PATH"] = [
53-
Gem.ports_bin_paths,
53+
Gem.ports_bin_and_lib_paths,
5454
old_path
5555
].flatten.join File::PATH_SEPARATOR
5656

@@ -65,7 +65,7 @@ def find_bin
6565
end
6666

6767
def find_exe
68-
Gem.ports_bin_paths.each do |bin|
68+
Gem.ports_bin_and_lib_paths.each do |bin|
6969
@exts.each do |ext|
7070
f = File.join bin, "#{name}#{ext}"
7171
return f if File.exist?(f)

lib/tiny_tds/gem.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
require "rbconfig"
2-
31
module TinyTds
42
module Gem
53
class << self
@@ -11,12 +9,14 @@ def ports_root_path
119
File.join(root_path, "ports")
1210
end
1311

14-
def ports_bin_paths
15-
Dir.glob(File.join(ports_root_path, "**", "bin"))
12+
def ports_bin_and_lib_paths
13+
Dir.glob(File.join(ports_root_path, "#{gem_platform.cpu}-#{gem_platform.os}*", "{bin,lib}"))
1614
end
1715

18-
def ports_lib_paths
19-
Dir.glob(File.join(ports_root_path, "**", "lib"))
16+
private
17+
18+
def gem_platform
19+
::Gem::Platform.local
2020
end
2121
end
2222
end

test/bin/restore-from-native-gem.ps1

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ $gemToUnpack = "./tiny_tds-$gemVersion-$env:RUBY_ARCHITECTURE.gem"
44
Write-Host "Looking to unpack $gemToUnpack"
55
gem unpack --target ./tmp "$gemToUnpack"
66

7-
# Restore precompiled code
7+
# Restore precompiled code (Gem code)
88
$source = (Resolve-Path ".\tmp\tiny_tds-$gemVersion-$env:RUBY_ARCHITECTURE\lib\tiny_tds").Path
99
$destination = (Resolve-Path ".\lib\tiny_tds").Path
1010
Get-ChildItem $source -Recurse -Exclude "*.rb" | Copy-Item -Destination {Join-Path $destination $_.FullName.Substring($source.length)}
11+
12+
# Restore precompiled code (ports)
13+
$source = (Resolve-Path ".\tmp\tiny_tds-$gemVersion-$env:RUBY_ARCHITECTURE\ports").Path
14+
New-Item -ItemType Directory -Path ".\ports" -Force
15+
$destination = (Resolve-Path ".\ports").Path
16+
Get-ChildItem $source -Recurse -Exclude "*.rb" | Copy-Item -Destination {Join-Path $destination $_.FullName.Substring($source.length)}

test/gem_test.rb

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ class GemTest < Minitest::Spec
77
describe TinyTds::Gem do
88
# We're going to muck with some system globals so lets make sure
99
# they get set back later
10-
original_platform = RbConfig::CONFIG["arch"]
1110
original_pwd = Dir.pwd
1211

1312
after do
14-
RbConfig::CONFIG["arch"] = original_platform
1513
Dir.chdir original_pwd
1614
end
1715

@@ -43,56 +41,53 @@ class GemTest < Minitest::Spec
4341
end
4442
end
4543

46-
describe "#ports_bin_paths" do
47-
let(:ports_bin_paths) { TinyTds::Gem.ports_bin_paths }
44+
describe "#ports_bin_and_lib_paths" do
45+
let(:ports_bin_and_lib_paths) { TinyTds::Gem.ports_bin_and_lib_paths }
4846

4947
describe "when the ports directories exist" do
50-
let(:fake_bin_paths) do
51-
ports_host_root = File.join(gem_root, "ports", "fake-host-with-dirs")
52-
[
53-
File.join("a", "bin"),
54-
File.join("a", "inner", "bin"),
55-
File.join("b", "bin")
56-
].map do |p|
48+
let(:fake_bin_and_lib_path) do
49+
ports_host_root = File.join(gem_root, "ports", "x86_64-unknown")
50+
["bin", "lib"].map do |p|
5751
File.join(ports_host_root, p)
5852
end
5953
end
6054

6155
before do
62-
RbConfig::CONFIG["arch"] = "fake-host-with-dirs"
63-
fake_bin_paths.each do |path|
56+
fake_bin_and_lib_path.each do |path|
6457
FileUtils.mkdir_p(path)
6558
end
6659
end
6760

6861
after do
6962
FileUtils.remove_entry_secure(
70-
File.join(gem_root, "ports", "fake-host-with-dirs"), true
63+
File.join(gem_root, "ports", "x86_64-unknown"), true
7164
)
7265
end
7366

7467
it "should return all the bin directories" do
75-
_(ports_bin_paths.sort).must_equal fake_bin_paths.sort
76-
end
68+
fake_platform = Gem::Platform.new("x86_64-unknown")
69+
70+
Gem::Platform.stub(:local, fake_platform) do
71+
_(ports_bin_and_lib_paths.sort).must_equal fake_bin_and_lib_path.sort
7772

78-
it "should return all the bin directories regardless of cwd" do
79-
Dir.chdir "/"
80-
_(ports_bin_paths.sort).must_equal fake_bin_paths.sort
73+
# should return the same regardless of path
74+
Dir.chdir "/"
75+
_(ports_bin_and_lib_paths.sort).must_equal fake_bin_and_lib_path.sort
76+
end
8177
end
8278
end
8379

8480
describe "when the ports directories are missing" do
85-
before do
86-
RbConfig::CONFIG["arch"] = "fake-host-without-dirs"
87-
end
88-
8981
it "should return no directories" do
90-
_(ports_bin_paths).must_be_empty
91-
end
82+
fake_platform = Gem::Platform.new("x86_64-unknown")
9283

93-
it "should return no directories regardless of cwd" do
94-
Dir.chdir "/"
95-
_(ports_bin_paths).must_be_empty
84+
Gem::Platform.stub(:local, fake_platform) do
85+
_(ports_bin_and_lib_paths).must_be_empty
86+
87+
# should be empty regardless of path
88+
Dir.chdir "/"
89+
_(ports_bin_and_lib_paths).must_be_empty
90+
end
9691
end
9792
end
9893
end

0 commit comments

Comments
 (0)