9a73b634ab
This adds an ID-less table containing one row per file, per merge request diff. It has a column for each attribute on Gitlab::Git::Diff that is serialised currently, with the advantage that we can easily query the attributes of this new table. It does not migrate existing data, so we have fallback code when the legacy st_diffs column is present instead. For a merge request diff to be valid, it should have at most one of: * Rows in this new table, with the correct merge_request_diff_id. * A non-NULL st_diffs column. It may have neither, if the diff is empty.
233 lines
6.4 KiB
Ruby
233 lines
6.4 KiB
Ruby
require 'spec_helper'
|
|
|
|
describe Gitlab::Database, lib: true do
|
|
before do
|
|
stub_const('MigrationTest', Class.new { include Gitlab::Database })
|
|
end
|
|
|
|
describe '.config' do
|
|
it 'returns a Hash' do
|
|
expect(described_class.config).to be_an_instance_of(Hash)
|
|
end
|
|
end
|
|
|
|
describe '.adapter_name' do
|
|
it 'returns the name of the adapter' do
|
|
expect(described_class.adapter_name).to be_an_instance_of(String)
|
|
end
|
|
end
|
|
|
|
# These are just simple smoke tests to check if the methods work (regardless
|
|
# of what they may return).
|
|
describe '.mysql?' do
|
|
subject { described_class.mysql? }
|
|
|
|
it { is_expected.to satisfy { |val| val == true || val == false } }
|
|
end
|
|
|
|
describe '.postgresql?' do
|
|
subject { described_class.postgresql? }
|
|
|
|
it { is_expected.to satisfy { |val| val == true || val == false } }
|
|
end
|
|
|
|
describe '.version' do
|
|
context "on mysql" do
|
|
it "extracts the version number" do
|
|
allow(described_class).to receive(:database_version).
|
|
and_return("5.7.12-standard")
|
|
|
|
expect(described_class.version).to eq '5.7.12-standard'
|
|
end
|
|
end
|
|
|
|
context "on postgresql" do
|
|
it "extracts the version number" do
|
|
allow(described_class).to receive(:database_version).
|
|
and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0")
|
|
|
|
expect(described_class.version).to eq '9.4.4'
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.nulls_last_order' do
|
|
context 'when using PostgreSQL' do
|
|
before do
|
|
expect(described_class).to receive(:postgresql?).and_return(true)
|
|
end
|
|
|
|
it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column ASC NULLS LAST'}
|
|
it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC NULLS LAST'}
|
|
end
|
|
|
|
context 'when using MySQL' do
|
|
before do
|
|
expect(described_class).to receive(:postgresql?).and_return(false)
|
|
end
|
|
|
|
it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column IS NULL, column ASC'}
|
|
it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC'}
|
|
end
|
|
end
|
|
|
|
describe '.nulls_first_order' do
|
|
context 'when using PostgreSQL' do
|
|
before do
|
|
expect(described_class).to receive(:postgresql?).and_return(true)
|
|
end
|
|
|
|
it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC NULLS FIRST'}
|
|
it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column DESC NULLS FIRST'}
|
|
end
|
|
|
|
context 'when using MySQL' do
|
|
before do
|
|
expect(described_class).to receive(:postgresql?).and_return(false)
|
|
end
|
|
|
|
it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC'}
|
|
it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column IS NULL, column DESC'}
|
|
end
|
|
end
|
|
|
|
describe '.with_connection_pool' do
|
|
it 'creates a new connection pool and disconnect it after used' do
|
|
closed_pool = nil
|
|
|
|
described_class.with_connection_pool(1) do |pool|
|
|
pool.with_connection do |connection|
|
|
connection.execute('SELECT 1 AS value')
|
|
end
|
|
|
|
expect(pool).to be_connected
|
|
|
|
closed_pool = pool
|
|
end
|
|
|
|
expect(closed_pool).not_to be_connected
|
|
end
|
|
|
|
it 'disconnects the pool even an exception was raised' do
|
|
error = Class.new(RuntimeError)
|
|
closed_pool = nil
|
|
|
|
begin
|
|
described_class.with_connection_pool(1) do |pool|
|
|
pool.with_connection do |connection|
|
|
connection.execute('SELECT 1 AS value')
|
|
end
|
|
|
|
closed_pool = pool
|
|
|
|
raise error.new('boom')
|
|
end
|
|
rescue error
|
|
end
|
|
|
|
expect(closed_pool).not_to be_connected
|
|
end
|
|
end
|
|
|
|
describe '.bulk_insert' do
|
|
before do
|
|
allow(described_class).to receive(:connection).and_return(connection)
|
|
allow(connection).to receive(:quote_column_name, &:itself)
|
|
allow(connection).to receive(:quote, &:itself)
|
|
allow(connection).to receive(:execute)
|
|
end
|
|
|
|
let(:connection) { double(:connection) }
|
|
|
|
let(:rows) do
|
|
[
|
|
{ a: 1, b: 2, c: 3 },
|
|
{ c: 6, a: 4, b: 5 }
|
|
]
|
|
end
|
|
|
|
it 'does nothing with empty rows' do
|
|
expect(connection).not_to receive(:execute)
|
|
|
|
described_class.bulk_insert('test', [])
|
|
end
|
|
|
|
it 'uses the ordering from the first row' do
|
|
expect(connection).to receive(:execute) do |sql|
|
|
expect(sql).to include('(1, 2, 3)')
|
|
expect(sql).to include('(4, 5, 6)')
|
|
end
|
|
|
|
described_class.bulk_insert('test', rows)
|
|
end
|
|
|
|
it 'quotes column names' do
|
|
expect(connection).to receive(:quote_column_name).with(:a)
|
|
expect(connection).to receive(:quote_column_name).with(:b)
|
|
expect(connection).to receive(:quote_column_name).with(:c)
|
|
|
|
described_class.bulk_insert('test', rows)
|
|
end
|
|
|
|
it 'quotes values' do
|
|
1.upto(6) do |i|
|
|
expect(connection).to receive(:quote).with(i)
|
|
end
|
|
|
|
described_class.bulk_insert('test', rows)
|
|
end
|
|
end
|
|
|
|
describe '.create_connection_pool' do
|
|
it 'creates a new connection pool with specific pool size' do
|
|
pool = described_class.create_connection_pool(5)
|
|
|
|
begin
|
|
expect(pool)
|
|
.to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
|
|
|
expect(pool.spec.config[:pool]).to eq(5)
|
|
ensure
|
|
pool.disconnect!
|
|
end
|
|
end
|
|
|
|
it 'allows setting of a custom hostname' do
|
|
pool = described_class.create_connection_pool(5, '127.0.0.1')
|
|
|
|
begin
|
|
expect(pool.spec.config[:host]).to eq('127.0.0.1')
|
|
ensure
|
|
pool.disconnect!
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#true_value' do
|
|
it 'returns correct value for PostgreSQL' do
|
|
expect(described_class).to receive(:postgresql?).and_return(true)
|
|
|
|
expect(described_class.true_value).to eq "'t'"
|
|
end
|
|
|
|
it 'returns correct value for MySQL' do
|
|
expect(described_class).to receive(:postgresql?).and_return(false)
|
|
|
|
expect(described_class.true_value).to eq 1
|
|
end
|
|
end
|
|
|
|
describe '#false_value' do
|
|
it 'returns correct value for PostgreSQL' do
|
|
expect(described_class).to receive(:postgresql?).and_return(true)
|
|
|
|
expect(described_class.false_value).to eq "'f'"
|
|
end
|
|
|
|
it 'returns correct value for MySQL' do
|
|
expect(described_class).to receive(:postgresql?).and_return(false)
|
|
|
|
expect(described_class.false_value).to eq 0
|
|
end
|
|
end
|
|
end
|