22
33module ActiveRecord
44 module Tenanted
5- module DatabaseAdapters
6- class SQLite # :nodoc:
5+ module DatabaseAdapters # :nodoc:
6+ #
7+ # TODO: This still feels to me like it's not _quite_ right. I think we could further refactor this by:
8+ #
9+ # 1. Moving tenant_databases and validate_tenant_name to BaseConfig, and subclassing it for
10+ # each database
11+ # 2. Moving create_database, drop_database, database_exist?, database_ready?,
12+ # acquire_ready_lock, ensure_database_directory_exists, and database_path to the SQLite
13+ # connection adapter, possibly into Rails
14+ # 3. Moving test_workerize and path_for to be SQLite connection adapter class methods,
15+ # possibly into Rails
16+ #
17+ class SQLite
18+ attr_reader :db_config
19+
720 def initialize ( db_config )
821 @db_config = db_config
922 end
1023
24+ def tenant_databases
25+ glob = path_for ( db_config . database_for ( "*" ) )
26+ scanner = Regexp . new ( path_for ( db_config . database_for ( "(.+)" ) ) )
27+
28+ Dir . glob ( glob ) . filter_map do |path |
29+ result = path . scan ( scanner ) . flatten . first
30+ if result . nil?
31+ Rails . logger . warn "ActiveRecord::Tenanted: Cannot parse tenant name from filename #{ path . inspect } "
32+ end
33+ result
34+ end
35+ end
36+
37+ def validate_tenant_name ( tenant_name )
38+ if tenant_name . match? ( %r{[/'"`]} )
39+ raise BadTenantNameError , "Tenant name contains an invalid character: #{ tenant_name . inspect } "
40+ end
41+ end
42+
1143 def create_database
1244 ensure_database_directory_exists
1345 FileUtils . touch ( database_path )
@@ -28,29 +60,10 @@ def database_ready?
2860 File . exist? ( database_path ) && !ActiveRecord ::Tenanted ::Mutex ::Ready . locked? ( database_path )
2961 end
3062
31- def tenant_databases
32- glob = db_config . database_path_for ( "*" )
33- scanner = Regexp . new ( db_config . database_path_for ( "(.+)" ) )
34-
35- Dir . glob ( glob ) . filter_map do |path |
36- result = path . scan ( scanner ) . flatten . first
37- if result . nil?
38- Rails . logger . warn "ActiveRecord::Tenanted: Cannot parse tenant name from filename #{ path . inspect } "
39- end
40- result
41- end
42- end
43-
4463 def acquire_ready_lock ( &block )
4564 ActiveRecord ::Tenanted ::Mutex ::Ready . lock ( database_path , &block )
4665 end
4766
48- def validate_tenant_name ( tenant_name )
49- if tenant_name . match? ( %r{[/'"`]} )
50- raise BadTenantNameError , "Tenant name contains an invalid character: #{ tenant_name . inspect } "
51- end
52- end
53-
5467 def ensure_database_directory_exists
5568 return unless database_path
5669
@@ -60,25 +73,32 @@ def ensure_database_directory_exists
6073 end
6174 end
6275
63- private
64- attr_reader :db_config
76+ def database_path
77+ path_for ( db_config . database )
78+ end
79+
80+ def test_workerize ( db , test_worker_id )
81+ test_worker_suffix = "_#{ test_worker_id } "
6582
66- def database_path
67- coerce_path ( db_config . database )
83+ if db . start_with? ( "file:" ) && db . include? ( "?" )
84+ db . sub ( /(\? .*)$/ , "#{ test_worker_suffix } \\ 1" )
85+ else
86+ db + test_worker_suffix
6887 end
88+ end
6989
70- # A sqlite database path can be a file path or a URI (either relative or absolute). We
71- # can't parse it as a standard URI in all circumstances, though, see
72- # https://sqlite.org/uri.html
73- def coerce_path ( path )
74- if path . start_with? ( "file:/" )
75- URI . parse ( path ) . path
76- elsif path . start_with? ( "file:" )
77- URI . parse ( path . sub ( /\? .*$/ , "" ) ) . opaque
78- else
79- path
80- end
90+ # A sqlite database path can be a file path or a URI (either relative or absolute). We
91+ # can't parse it as a standard URI in all circumstances, though, see
92+ # https://sqlite.org/uri.html
93+ def path_for ( database )
94+ if database . start_with? ( "file:/" )
95+ URI . parse ( database ) . path
96+ elsif database . start_with? ( "file:" )
97+ URI . parse ( database . sub ( /\? .*$/ , "" ) ) . opaque
98+ else
99+ database
81100 end
101+ end
82102 end
83103 end
84104 end
0 commit comments