summaryrefslogtreecommitdiff
path: root/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters
diff options
context:
space:
mode:
authorhukl <contact@smyck.org>2009-04-28 00:15:53 +0200
committerhukl <contact@smyck.org>2009-05-01 17:14:02 +0200
commit4bd16f053847f2efe347ebda9136ef2233ee0d2c (patch)
treef4c11f89455de991c8d87726d5757b752e7129e2 /vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters
parentd3a9b46ba5c863a0ff377dcffae9a494fe476e02 (diff)
added thinking_sphinx plugin for fulltext search on nodes and heads
Diffstat (limited to 'vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters')
-rw-r--r--vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/abstract_adapter.rb42
-rw-r--r--vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/mysql_adapter.rb54
-rw-r--r--vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/postgresql_adapter.rb130
3 files changed, 226 insertions, 0 deletions
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/abstract_adapter.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/abstract_adapter.rb
new file mode 100644
index 0000000..b68b75e
--- /dev/null
+++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/abstract_adapter.rb
@@ -0,0 +1,42 @@
1module ThinkingSphinx
2 class AbstractAdapter
3 def initialize(model)
4 @model = model
5 end
6
7 def setup
8 # Deliberately blank - subclasses should do something though. Well, if
9 # they need to.
10 end
11
12 def self.detect(model)
13 case model.connection.class.name
14 when "ActiveRecord::ConnectionAdapters::MysqlAdapter",
15 "ActiveRecord::ConnectionAdapters::MysqlplusAdapter"
16 ThinkingSphinx::MysqlAdapter.new model
17 when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
18 ThinkingSphinx::PostgreSQLAdapter.new model
19 when "ActiveRecord::ConnectionAdapters::JdbcAdapter"
20 if model.connection.config[:adapter] == "jdbcmysql"
21 ThinkingSphinx::MysqlAdapter.new model
22 elsif model.connection.config[:adapter] == "jdbcpostgresql"
23 ThinkingSphinx::PostgreSQLAdapter.new model
24 else
25 raise "Invalid Database Adapter: Sphinx only supports MySQL and PostgreSQL"
26 end
27 else
28 raise "Invalid Database Adapter: Sphinx only supports MySQL and PostgreSQL, not #{model.connection.class.name}"
29 end
30 end
31
32 def quote_with_table(column)
33 "#{@model.quoted_table_name}.#{@model.connection.quote_column_name(column)}"
34 end
35
36 protected
37
38 def connection
39 @connection ||= @model.connection
40 end
41 end
42end
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/mysql_adapter.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/mysql_adapter.rb
new file mode 100644
index 0000000..597d4b6
--- /dev/null
+++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/mysql_adapter.rb
@@ -0,0 +1,54 @@
1module ThinkingSphinx
2 class MysqlAdapter < AbstractAdapter
3 def setup
4 # Does MySQL actually need to do anything?
5 end
6
7 def sphinx_identifier
8 "mysql"
9 end
10
11 def concatenate(clause, separator = ' ')
12 "CONCAT_WS('#{separator}', #{clause})"
13 end
14
15 def group_concatenate(clause, separator = ' ')
16 "GROUP_CONCAT(DISTINCT #{clause} SEPARATOR '#{separator}')"
17 end
18
19 def cast_to_string(clause)
20 "CAST(#{clause} AS CHAR)"
21 end
22
23 def cast_to_datetime(clause)
24 "UNIX_TIMESTAMP(#{clause})"
25 end
26
27 def cast_to_unsigned(clause)
28 "CAST(#{clause} AS UNSIGNED)"
29 end
30
31 def convert_nulls(clause, default = '')
32 default = "'#{default}'" if default.is_a?(String)
33
34 "IFNULL(#{clause}, #{default})"
35 end
36
37 def boolean(value)
38 value ? 1 : 0
39 end
40
41 def crc(clause, blank_to_null = false)
42 clause = "NULLIF(#{clause},'')" if blank_to_null
43 "CRC32(#{clause})"
44 end
45
46 def utf8_query_pre
47 "SET NAMES utf8"
48 end
49
50 def time_difference(diff)
51 "DATE_SUB(NOW(), INTERVAL #{diff} SECOND)"
52 end
53 end
54end \ No newline at end of file
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/postgresql_adapter.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/postgresql_adapter.rb
new file mode 100644
index 0000000..625971d
--- /dev/null
+++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/adapters/postgresql_adapter.rb
@@ -0,0 +1,130 @@
1module ThinkingSphinx
2 class PostgreSQLAdapter < AbstractAdapter
3 def setup
4 create_array_accum_function
5 create_crc32_function
6 end
7
8 def sphinx_identifier
9 "pgsql"
10 end
11
12 def concatenate(clause, separator = ' ')
13 clause.split(', ').collect { |field|
14 "COALESCE(CAST(#{field} as varchar), '')"
15 }.join(" || '#{separator}' || ")
16 end
17
18 def group_concatenate(clause, separator = ' ')
19 "array_to_string(array_accum(#{clause}), '#{separator}')"
20 end
21
22 def cast_to_string(clause)
23 clause
24 end
25
26 def cast_to_datetime(clause)
27 "cast(extract(epoch from #{clause}) as int)"
28 end
29
30 def cast_to_unsigned(clause)
31 clause
32 end
33
34 def convert_nulls(clause, default = '')
35 default = "'#{default}'" if default.is_a?(String)
36
37 "COALESCE(#{clause}, #{default})"
38 end
39
40 def boolean(value)
41 value ? 'TRUE' : 'FALSE'
42 end
43
44 def crc(clause, blank_to_null = false)
45 clause = "NULLIF(#{clause},'')" if blank_to_null
46 "crc32(#{clause})"
47 end
48
49 def utf8_query_pre
50 nil
51 end
52
53 def time_difference(diff)
54 "current_timestamp - interval '#{diff} seconds'"
55 end
56
57 private
58
59 def execute(command, output_error = false)
60 connection.execute "begin"
61 connection.execute "savepoint ts"
62 begin
63 connection.execute command
64 rescue StandardError => err
65 puts err if output_error
66 connection.execute "rollback to savepoint ts"
67 end
68 connection.execute "release savepoint ts"
69 connection.execute "commit"
70 end
71
72 def create_array_accum_function
73 if connection.raw_connection.respond_to?(:server_version) && connection.raw_connection.server_version > 80200
74 execute <<-SQL
75 CREATE AGGREGATE array_accum (anyelement)
76 (
77 sfunc = array_append,
78 stype = anyarray,
79 initcond = '{}'
80 );
81 SQL
82 else
83 execute <<-SQL
84 CREATE AGGREGATE array_accum
85 (
86 basetype = anyelement,
87 sfunc = array_append,
88 stype = anyarray,
89 initcond = '{}'
90 );
91 SQL
92 end
93 end
94
95 def create_crc32_function
96 execute "CREATE LANGUAGE 'plpgsql';"
97 function = <<-SQL
98 CREATE OR REPLACE FUNCTION crc32(word text)
99 RETURNS bigint AS $$
100 DECLARE tmp bigint;
101 DECLARE i int;
102 DECLARE j int;
103 DECLARE word_array bytea;
104 BEGIN
105 i = 0;
106 tmp = 4294967295;
107 word_array = decode(replace(word, E'\\\\', E'\\\\\\\\'), 'escape');
108 LOOP
109 tmp = (tmp # get_byte(word_array, i))::bigint;
110 i = i + 1;
111 j = 0;
112 LOOP
113 tmp = ((tmp >> 1) # (3988292384 * (tmp & 1)))::bigint;
114 j = j + 1;
115 IF j >= 8 THEN
116 EXIT;
117 END IF;
118 END LOOP;
119 IF i >= char_length(word) THEN
120 EXIT;
121 END IF;
122 END LOOP;
123 return (tmp # 4294967295);
124 END
125 $$ IMMUTABLE STRICT LANGUAGE plpgsql;
126 SQL
127 execute function, true
128 end
129 end
130end \ No newline at end of file