|
| 1 | +# Spannerlib Ruby Wrapper |
| 2 | + |
| 3 | +This Ruby wrapper provides an interface for interacting with Google Cloud Spanner via native code, leveraging [FFI (Foreign Function Interface)](https://github.com/ffi/ffi) to connect Ruby with native libraries—such as C or Go (compiled via cgo). It is part of the [`go-sql-spanner`](https://github.com/googleapis/go-sql-spanner) project and enables Ruby applications to utilize high-performance, native Spanner features. |
| 4 | + |
| 5 | +## What Does This Wrapper Do? |
| 6 | + |
| 7 | +- **FFI Integration:** Bridges Ruby with native C (or Go via cgo) code by wrapping native functions using FFI. |
| 8 | +- **High Performance:** Provides access to Spanner's performance and reliability through idiomatic Ruby APIs. |
| 9 | +- **Mock Server & Testing:** Includes mock server and integration tests to validate functionality. |
| 10 | + |
| 11 | +## Getting Started |
| 12 | + |
| 13 | +### Prerequisites |
| 14 | + |
| 15 | +- Ruby (>= 2.6) |
| 16 | +- [Bundler](https://bundler.io/): `gem install bundler` |
| 17 | +- [FFI Gem](https://github.com/ffi/ffi) (included in Gemfile) |
| 18 | +- Go (if building native libraries from source) |
| 19 | + |
| 20 | +### Setup |
| 21 | + |
| 22 | +Install Ruby dependencies: |
| 23 | + |
| 24 | +```sh |
| 25 | +bundle install |
| 26 | +``` |
| 27 | + |
| 28 | +## FFI & Native Integration |
| 29 | + |
| 30 | +This wrapper uses the [FFI Ruby gem](https://github.com/ffi/ffi) to load and call native functions implemented in C (or Go via cgo). |
| 31 | + |
| 32 | +FFI setup is located in [`lib/spannerlib/ffi.rb`](lib/spannerlib/ffi.rb). |
| 33 | +Refer to the source code [`lib/spannerlib/ffi.rb`](lib/spannerlib/ffi.rb) for details on function signatures and internals. |
| 34 | + |
| 35 | +## Running Tests |
| 36 | + |
| 37 | +### Mock Server Tests |
| 38 | + |
| 39 | +These tests run against an in-memory GRPC mock server. |
| 40 | + |
| 41 | +```sh |
| 42 | +bundle exec rspec spec/spannerlib_ruby_spec.rb |
| 43 | +``` |
| 44 | + |
| 45 | +### Integration Tests |
| 46 | + |
| 47 | +Integration tests are run against the [Google Spanner Emulator](https://cloud.google.com/spanner/docs/emulator). |
| 48 | + |
| 49 | +Start the emulator using Docker (recommended): |
| 50 | + |
| 51 | +```sh |
| 52 | +docker run --rm -d \ |
| 53 | + -p 9010:9010 \ |
| 54 | + gcr.io/cloud-spanner-emulator/emulator |
| 55 | +``` |
| 56 | + |
| 57 | +Then set the environment variable to direct client library calls to the emulator: |
| 58 | + |
| 59 | +```sh |
| 60 | +export SPANNER_EMULATOR_HOST=localhost:9010 |
| 61 | +bundle exec rspec spec/integration/ |
| 62 | +``` |
| 63 | + |
| 64 | +## Linting & Fixes |
| 65 | + |
| 66 | +To check and auto-correct Ruby code style: |
| 67 | + |
| 68 | +```sh |
| 69 | +bundle exec rubocop # Checks lint |
| 70 | +bundle exec rubocop -A # Auto-corrects where possible |
| 71 | +``` |
| 72 | + |
| 73 | +If any linting issues remain, resolve those manually. |
| 74 | + |
| 75 | +## Contributing |
| 76 | + |
| 77 | +We welcome contributions! Please follow these steps: |
| 78 | + |
| 79 | +1. Fork and clone this repository. |
| 80 | +2. Install dependencies with `bundle install`. |
| 81 | +3. Build any necessary native libraries if required. |
| 82 | +4. Run linting and tests before submitting a PR. |
| 83 | +5. Use clear commit messages (e.g., `chore(ruby): ...`). |
| 84 | + |
| 85 | +Feel free to open issues or pull requests for improvements. |
| 86 | + |
| 87 | +## Troubleshooting |
| 88 | + |
| 89 | +- **FFI Load Errors:** Ensure required native libraries are built and in your library path. |
| 90 | +- **Missing Gems:** Run `bundle install`. |
| 91 | +- **Spanner Credentials Issues:** Set up [Application Default Credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc), for example by setting the `GOOGLE_APPLICATION_CREDENTIALS` environment variable. |
| 92 | + |
| 93 | +--- |
| 94 | + |
| 95 | +For overall project details, see the main [go-sql-spanner README](../../../README.md). |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +**Reference:** |
| 100 | +For examples of adding new functionality inside the FFI layer, see [PR #655](https://github.com/googleapis/go-sql-spanner/pull/655). |
| 101 | + |
| 102 | +## Building and Packaging the Ruby Gem |
| 103 | + |
| 104 | +Building native binaries for the Ruby wrapper (`spannerlib-ruby`) and publishing them as a Ruby gem is automated via GitHub Actions. |
| 105 | + |
| 106 | +### How it Works |
| 107 | + |
| 108 | +- Native shared libraries for Linux, macOS, and Windows are cross-compiled using GitHub-hosted runners and cross-compilers. |
| 109 | +- The binaries are packaged as part of the Ruby gem. |
| 110 | +- The process is defined in the [`release-ruby-wrapper.yml`](../../../.github/workflows/release-ruby-wrapper.yml) workflow file: |
| 111 | + - Three main stages: |
| 112 | + 1. **Compilation:** Builds platform-specific binaries for Linux, macOS, and Windows. |
| 113 | + 2. **Artifact Upload:** Compiled binaries are uploaded for later packaging. |
| 114 | + 3. **Gem Packaging and Publishing:** The gem is built from source and published to RubyGems automatically if the workflow is manually dispatched. |
| 115 | + |
| 116 | +Please see the [GitHub Actions workflow file](../../../.github/workflows/release-ruby-wrapper.yml) for full implementation details. |
| 117 | + |
| 118 | +--- |
| 119 | + |
| 120 | +**Note:** If you want to manually build the gem locally for testing, you can run the following from within `spannerlib/wrappers/spannerlib-ruby`: |
| 121 | + |
| 122 | +```sh |
| 123 | +gem build spannerlib-ruby.gemspec |
| 124 | +``` |
| 125 | + |
| 126 | +For publishing, refer to [RubyGems guides](https://guides.rubygems.org/publishing/) or use the automated workflow. |
0 commit comments