diff options
162 files changed, 11878 insertions, 1 deletions
| @@ -1,4 +1,4 @@ | |||
| 1 | *.log | 1 | log/* |
| 2 | database.yml | 2 | database.yml |
| 3 | schema.rb | 3 | schema.rb |
| 4 | .DS_Store | 4 | .DS_Store |
| @@ -15,3 +15,5 @@ lib/chaos_calendar/ical_occurrences_wrap.o | |||
| 15 | db/authors.csv | 15 | db/authors.csv |
| 16 | public/system | 16 | public/system |
| 17 | vendor/plugins/paperclip/tmp | 17 | vendor/plugins/paperclip/tmp |
| 18 | db/sphinx | ||
| 19 | config/*.sphinx.conf \ No newline at end of file | ||
diff --git a/app/models/node.rb b/app/models/node.rb index 98fe94f..4ebb3a7 100644 --- a/app/models/node.rb +++ b/app/models/node.rb | |||
| @@ -17,6 +17,11 @@ class Node < ActiveRecord::Base | |||
| 17 | # Validations | 17 | # Validations |
| 18 | # validates_length_of :slug, :within => 3..40 | 18 | # validates_length_of :slug, :within => 3..40 |
| 19 | 19 | ||
| 20 | # Index for Fulltext Search | ||
| 21 | define_index do | ||
| 22 | indexes head.globalize_translations.title | ||
| 23 | end | ||
| 24 | |||
| 20 | # Class methods | 25 | # Class methods |
| 21 | 26 | ||
| 22 | # Returns a page for a given node. If no revision is supplied, it returns | 27 | # Returns a page for a given node. If no revision is supplied, it returns |
diff --git a/vendor/plugins/thinking-sphinx/LICENCE b/vendor/plugins/thinking-sphinx/LICENCE new file mode 100644 index 0000000..e031e3c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/LICENCE | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | Copyright (c) 2008 Pat Allan | ||
| 2 | |||
| 3 | Permission is hereby granted, free of charge, to any person obtaining | ||
| 4 | a copy of this software and associated documentation files (the | ||
| 5 | "Software"), to deal in the Software without restriction, including | ||
| 6 | without limitation the rights to use, copy, modify, merge, publish, | ||
| 7 | distribute, sublicense, and/or sell copies of the Software, and to | ||
| 8 | permit persons to whom the Software is furnished to do so, subject to | ||
| 9 | the following conditions: | ||
| 10 | |||
| 11 | The above copyright notice and this permission notice shall be | ||
| 12 | included in all copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
| 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
| 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/vendor/plugins/thinking-sphinx/README b/vendor/plugins/thinking-sphinx/README new file mode 100644 index 0000000..e33cc3e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/README | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | = Thinking Sphinx | ||
| 2 | |||
| 3 | == Usage | ||
| 4 | |||
| 5 | First, if you haven't done so already, check out the main usage[http://ts.freelancing-gods.com/usage.html] page. Once you've done that, the next place to look for information is the specific method docs - ThinkingSphinx::Search and ThinkingSphinx::Index::Builder in particular. | ||
| 6 | |||
| 7 | Keep in mind that while Thinking Sphinx works for ActiveRecord with Merb, it doesn't yet support DataMapper (although that is planned). | ||
| 8 | |||
| 9 | == Contributing | ||
| 10 | |||
| 11 | Fork on GitHub and after you've committed tested patches, send a pull request. | ||
| 12 | |||
| 13 | To quickly see if your system is ready to run the thinking sphinx specs, run the contribute.rb script found in the project root directory. Use the following instructions to install any missing requirements. | ||
| 14 | |||
| 15 | To get the spec suite running, you will need to install the not-a-mock gem if you don't already have it: | ||
| 16 | |||
| 17 | git clone git://github.com/freelancing-god/not-a-mock.git | ||
| 18 | cd not-a-mock | ||
| 19 | rake gem | ||
| 20 | gem install pkg/not_a_mock-1.1.0.gem | ||
| 21 | |||
| 22 | Then install the ginger gem. The steps are the same, except that you might need to sudo the gem install: | ||
| 23 | |||
| 24 | git clone git://github.com/freelancing-god/ginger.git | ||
| 25 | cd ginger | ||
| 26 | rake gem | ||
| 27 | sudo gem install pkg/ginger-1.1.0.gem | ||
| 28 | |||
| 29 | Then install the faker gem: | ||
| 30 | |||
| 31 | sudo gem install faker | ||
| 32 | |||
| 33 | Then set up your database: | ||
| 34 | |||
| 35 | cp spec/fixtures/database.yml.default spec/fixtures/database.yml | ||
| 36 | cp spec/fixtures/database.yml.default features/support/db/database.yml | ||
| 37 | mysqladmin -u root create thinking_sphinx | ||
| 38 | |||
| 39 | Make sure you don't have another Sphinx daemon (searchd) running. If you do, quit it with "rake ts:stop" | ||
| 40 | in the app root. | ||
| 41 | |||
| 42 | You should now have a passing test suite from which to build your patch on. | ||
| 43 | |||
| 44 | rake spec | ||
| 45 | rake features (Note: You will need MySQL and Postgres gems to run the full suite. You may want to tweak your rakefile) | ||
| 46 | |||
| 47 | If you get the message "Failed to start searchd daemon", run the spec with sudo: | ||
| 48 | |||
| 49 | sudo rake spec | ||
| 50 | sudo rake features | ||
| 51 | |||
| 52 | If you quit the spec suite before it's completed, you may be left with data in the test | ||
| 53 | database, causing the next run to have failures. Let that run complete and then try again. | ||
| 54 | |||
| 55 | == Contributors | ||
| 56 | |||
| 57 | Since I first released this library, there's been quite a few people who have submitted patches, to my immense gratitude. Others have suggested syntax changes and general improvements. So my thanks to the following people: | ||
| 58 | |||
| 59 | - Joost Hietbrink | ||
| 60 | - Jonathan Conway | ||
| 61 | - Gregory Mirzayantz | ||
| 62 | - Tung Nguyen | ||
| 63 | - Sean Cribbs | ||
| 64 | - Benoit Caccinolo | ||
| 65 | - John Barton | ||
| 66 | - Oliver Beddows | ||
| 67 | - Arthur Zapparoli | ||
| 68 | - Dusty Doris | ||
| 69 | - Marcus Crafter | ||
| 70 | - Patrick Lenz | ||
| 71 | - Björn Andreasson | ||
| 72 | - James Healy | ||
| 73 | - Jae-Jun Hwang | ||
| 74 | - Xavier Shay | ||
| 75 | - Jason Rust | ||
| 76 | - Gopal Patel | ||
| 77 | - Chris Heald | ||
| 78 | - Peter Vandenberk | ||
| 79 | - Josh French | ||
| 80 | - Andrew Bennett | ||
| 81 | - Jordan Fowler | ||
| 82 | - Seth Walker | ||
| 83 | - Joe Noon | ||
| 84 | - Wolfgang Postler | ||
| 85 | - Rick Olson | ||
| 86 | - Killian Murphy | ||
| 87 | - Morten Primdahl | ||
| 88 | - Ryan Bates | ||
| 89 | - David Eisinger | ||
| 90 | - Shay Arnett | ||
| 91 | - Minh Tran | ||
| 92 | - Jeremy Durham | ||
| 93 | - Piotr Sarnacki | ||
| 94 | - Matt Johnson | ||
| 95 | - Nicolas Blanco | ||
| 96 | - Max Lapshin | ||
| 97 | - Josh Natanson | ||
| 98 | - Philip Hallstrom | ||
| 99 | - Christian Rishøj | ||
| 100 | - Mike Flester | ||
| 101 | - Jim Remsik | ||
| 102 | - Kennon Ballou | ||
| 103 | - Henrik Nyh | ||
| 104 | - Emil Tin | ||
| 105 | - Doug Cole | ||
| 106 | - Ed Hickey | ||
| 107 | - Evan Weaver | ||
| 108 | - Thibaut Barrere | ||
| 109 | - Kristopher Chambers | ||
| 110 | - Dmitrij Smalko | ||
| 111 | - Aleksey Yeschenko | ||
| 112 | - Lachie Cox | ||
| 113 | - Lourens Naude | ||
| 114 | - Tom Davies | ||
| 115 | - Dan Pickett | ||
| 116 | - Alex Caudill | ||
| 117 | - Jim Benton | ||
| 118 | - John Aughey | ||
| 119 | - Keith Pitty | ||
| 120 | - Jeff Talbot | ||
| 121 | - Dana Contreras | ||
| 122 | - Menno van der Sman | ||
| 123 | - Bill Harding | ||
| 124 | - Isaac Feliu | ||
| 125 | - Andrei Bocan | ||
| 126 | - László Bácsi | ||
| 127 | - Peter Wagenet | ||
diff --git a/vendor/plugins/thinking-sphinx/README.textile b/vendor/plugins/thinking-sphinx/README.textile new file mode 100644 index 0000000..d19c8de --- /dev/null +++ b/vendor/plugins/thinking-sphinx/README.textile | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | h1. Thinking Sphinx | ||
| 2 | |||
| 3 | h2. Usage | ||
| 4 | |||
| 5 | First, if you haven't done so already, check out the main "usage":http://ts.freelancing-gods.com/usage.html page. Once you've done that, the next place to look for information is the specific method docs - ThinkingSphinx::Search and ThinkingSphinx::Index::Builder in particular. | ||
| 6 | |||
| 7 | Keep in mind that while Thinking Sphinx works for ActiveRecord with Merb, it doesn't yet support DataMapper (although that is planned). | ||
| 8 | |||
| 9 | h2. Contributing | ||
| 10 | |||
| 11 | Fork on GitHub and after you've committed tested patches, send a pull request. | ||
| 12 | |||
| 13 | To quickly see if your system is ready to run the thinking sphinx specs, run the contribute.rb script found in the project root directory. Use the following instructions to install any missing requirements. | ||
| 14 | |||
| 15 | To get the spec suite running, you will need to install the not-a-mock gem if you don't already have it: | ||
| 16 | |||
| 17 | git clone git://github.com/freelancing-god/not-a-mock.git | ||
| 18 | cd not-a-mock | ||
| 19 | rake gem | ||
| 20 | gem install pkg/not_a_mock-1.1.0.gem | ||
| 21 | |||
| 22 | Then install the ginger gem. The steps are the same, except that you might need to sudo the gem install: | ||
| 23 | |||
| 24 | git clone git://github.com/freelancing-god/ginger.git | ||
| 25 | cd ginger | ||
| 26 | rake gem | ||
| 27 | sudo gem install pkg/ginger-1.1.0.gem | ||
| 28 | |||
| 29 | Then set up your database: | ||
| 30 | |||
| 31 | cp spec/fixtures/database.yml.default spec/fixtures/database.yml | ||
| 32 | mysqladmin -u root create thinking_sphinx | ||
| 33 | |||
| 34 | Make sure you don't have another Sphinx daemon (searchd) running. If you do, quit it with "rake ts:stop" | ||
| 35 | in the app root. | ||
| 36 | |||
| 37 | You should now have a passing test suite from which to build your patch on. | ||
| 38 | |||
| 39 | rake spec | ||
| 40 | |||
| 41 | If you get the message "Failed to start searchd daemon", run the spec with sudo: | ||
| 42 | |||
| 43 | sudo rake spec | ||
| 44 | |||
| 45 | If you quit the spec suite before it's completed, you may be left with data in the test | ||
| 46 | database, causing the next run to have failures. Let that run complete and then try again. | ||
| 47 | |||
| 48 | h2. Contributors | ||
| 49 | |||
| 50 | Since I first released this library, there's been quite a few people who have submitted patches, to my immense gratitude. Others have suggested syntax changes and general improvements. So my thanks to the following people: | ||
| 51 | |||
| 52 | * Joost Hietbrink | ||
| 53 | * Jonathan Conway | ||
| 54 | * Gregory Mirzayantz | ||
| 55 | * Tung Nguyen | ||
| 56 | * Sean Cribbs | ||
| 57 | * Benoit Caccinolo | ||
| 58 | * John Barton | ||
| 59 | * Oliver Beddows | ||
| 60 | * Arthur Zapparoli | ||
| 61 | * Dusty Doris | ||
| 62 | * Marcus Crafter | ||
| 63 | * Patrick Lenz | ||
| 64 | * Björn Andreasson | ||
| 65 | * James Healy | ||
| 66 | * Jae-Jun Hwang | ||
| 67 | * Xavier Shay | ||
| 68 | * Jason Rust | ||
| 69 | * Gopal Patel | ||
| 70 | * Chris Heald | ||
| 71 | * Peter Vandenberk | ||
| 72 | * Josh French | ||
| 73 | * Andrew Bennett | ||
| 74 | * Jordan Fowler | ||
| 75 | * Seth Walker | ||
| 76 | * Joe Noon | ||
| 77 | * Wolfgang Postler | ||
| 78 | * Rick Olson | ||
| 79 | * Killian Murphy | ||
| 80 | * Morten Primdahl | ||
| 81 | * Ryan Bates | ||
| 82 | * David Eisinger | ||
| 83 | * Shay Arnett | ||
| 84 | * Minh Tran | ||
| 85 | * Jeremy Durham | ||
| 86 | * Piotr Sarnacki | ||
| 87 | * Matt Johnson | ||
| 88 | * Nicolas Blanco | ||
| 89 | * Max Lapshin | ||
| 90 | * Josh Natanson | ||
| 91 | * Philip Hallstrom | ||
| 92 | * Christian Rishøj | ||
| 93 | * Mike Flester | ||
| 94 | * Jim Remsik | ||
| 95 | * Kennon Ballou | ||
| 96 | * Henrik Nyh | ||
| 97 | * Emil Tin | ||
| 98 | * Doug Cole | ||
| 99 | * Ed Hickey | ||
| 100 | * Evan Weaver | ||
| 101 | * Thibaut Barrere | ||
| 102 | * Kristopher Chambers | ||
| 103 | * Dmitrij Smalko | ||
| 104 | * Aleksey Yeschenko | ||
| 105 | * Lachie Cox | ||
| 106 | * Lourens Naude | ||
| 107 | * Tom Davies | ||
| 108 | * Dan Pickett | ||
| 109 | * Alex Caudill | ||
| 110 | * Jim Benton | ||
| 111 | * John Aughey | ||
| 112 | * Keith Pitty | ||
| 113 | * Jeff Talbot | ||
| 114 | * Dana Contreras | ||
| 115 | * Menno van der Sman | ||
| 116 | * Bill Harding | ||
| 117 | * Isaac Feliu | ||
| 118 | * Andrei Bocan | ||
| 119 | * László Bácsi | ||
| 120 | * Peter Wagenet | ||
diff --git a/vendor/plugins/thinking-sphinx/Rakefile b/vendor/plugins/thinking-sphinx/Rakefile new file mode 100644 index 0000000..90cb5c4 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/Rakefile | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | require 'rubygems' | ||
| 2 | |||
| 3 | require 'tasks/distribution' | ||
| 4 | require 'tasks/testing' | ||
| 5 | |||
| 6 | require 'thinking_sphinx/tasks' \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/contribute.rb b/vendor/plugins/thinking-sphinx/contribute.rb new file mode 100755 index 0000000..315b438 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/contribute.rb | |||
| @@ -0,0 +1,332 @@ | |||
| 1 | #!/usr/bin/env ruby | ||
| 2 | |||
| 3 | require 'rubygems' | ||
| 4 | require 'yaml' | ||
| 5 | require 'pp' | ||
| 6 | |||
| 7 | module ContributeHelper; end | ||
| 8 | |||
| 9 | class Contribute | ||
| 10 | include ContributeHelper | ||
| 11 | |||
| 12 | def dependencies | ||
| 13 | [ | ||
| 14 | Dependencies::Sphinx, | ||
| 15 | Dependencies::Mysql, | ||
| 16 | Dependencies::AR, | ||
| 17 | Dependencies::Ginger | ||
| 18 | ] | ||
| 19 | end | ||
| 20 | |||
| 21 | def show | ||
| 22 | show_welcome_screen | ||
| 23 | |||
| 24 | ( | ||
| 25 | check_for_dependencies && | ||
| 26 | create_database_yaml && | ||
| 27 | check_mysql_is_working && | ||
| 28 | create_test_database | ||
| 29 | ) || exit(1) | ||
| 30 | |||
| 31 | show_done_screen | ||
| 32 | end | ||
| 33 | |||
| 34 | private | ||
| 35 | WELCOME_SCREEN = <<-EO_WELCOME | ||
| 36 | <banner>Thinking Sphinx Contribution</banner> | ||
| 37 | |||
| 38 | Thanks for contributing to Thinking Sphinx. | ||
| 39 | |||
| 40 | In this script we'll help you get setup to hack: | ||
| 41 | |||
| 42 | <b>1.</b> We'll check that you have the right software installed and running. | ||
| 43 | <b>2.</b> We'll set up the test database for specs to run against. | ||
| 44 | |||
| 45 | EO_WELCOME | ||
| 46 | |||
| 47 | DONE_SCREEN = <<-EO_DONE | ||
| 48 | <banner>Setup done!</banner> | ||
| 49 | |||
| 50 | All done! Now you can start hacking by running | ||
| 51 | |||
| 52 | <b>rake spec</b> | ||
| 53 | |||
| 54 | EO_DONE | ||
| 55 | |||
| 56 | REVIEW_YAML = <<-EO_REVIEW_YAML | ||
| 57 | |||
| 58 | Please review the database details in the yaml file details before continuing. | ||
| 59 | |||
| 60 | This file is used by the specs to connect to the database. | ||
| 61 | |||
| 62 | Current details: | ||
| 63 | EO_REVIEW_YAML | ||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | MYSQL_FAILED = <<-EO_MYSQL_FAILED | ||
| 68 | |||
| 69 | Looks like we couldn't successfully talk to the mysql database. | ||
| 70 | |||
| 71 | Don't worry though... | ||
| 72 | |||
| 73 | EO_MYSQL_FAILED | ||
| 74 | |||
| 75 | CREATE_DATABASE_FAILED = <<-EO_CREATE_DATABASE_FAILED | ||
| 76 | |||
| 77 | Looks like we couldn't create a test database to work against. | ||
| 78 | |||
| 79 | Don't worry though... | ||
| 80 | |||
| 81 | EO_CREATE_DATABASE_FAILED | ||
| 82 | |||
| 83 | def show_welcome_screen | ||
| 84 | colour_puts WELCOME_SCREEN | ||
| 85 | wait! | ||
| 86 | end | ||
| 87 | |||
| 88 | def show_done_screen | ||
| 89 | colour_puts DONE_SCREEN | ||
| 90 | end | ||
| 91 | |||
| 92 | # create database.yml | ||
| 93 | def create_database_yaml | ||
| 94 | colour_puts "<banner>creating database yaml</banner>" | ||
| 95 | puts | ||
| 96 | |||
| 97 | |||
| 98 | config = { | ||
| 99 | 'username' => 'root', | ||
| 100 | 'password' => nil, | ||
| 101 | 'host' => 'localhost' | ||
| 102 | } | ||
| 103 | |||
| 104 | |||
| 105 | colour_print " * <b>#{db_yml}</b>... " | ||
| 106 | unless File.exist?(db_yml) | ||
| 107 | open(db_yml,'w') {|f| f << config.to_yaml} | ||
| 108 | colour_puts "<green>created</green>" | ||
| 109 | else | ||
| 110 | config = YAML.load_file(db_yml) | ||
| 111 | colour_puts "<green>already exists</green>" | ||
| 112 | end | ||
| 113 | |||
| 114 | colour_puts REVIEW_YAML | ||
| 115 | |||
| 116 | config.each do |(k,v)| | ||
| 117 | colour_puts " * <b>#{k}</b>: #{v}" | ||
| 118 | end | ||
| 119 | |||
| 120 | puts | ||
| 121 | |||
| 122 | wait! | ||
| 123 | true | ||
| 124 | end | ||
| 125 | |||
| 126 | def check_mysql_is_working | ||
| 127 | require 'activerecord' | ||
| 128 | colour_puts "<banner>check mysql is working</banner>" | ||
| 129 | puts | ||
| 130 | |||
| 131 | connect_to_db | ||
| 132 | |||
| 133 | print " * connecting to mysql... " | ||
| 134 | |||
| 135 | begin | ||
| 136 | ActiveRecord::Base.connection.select_value('select sysdate() from dual') | ||
| 137 | |||
| 138 | colour_puts "<green>successful</green>" | ||
| 139 | puts | ||
| 140 | |||
| 141 | return true | ||
| 142 | rescue defined?(JRUBY_VERSION) ? Java::JavaSql::SQLException : Mysql::Error | ||
| 143 | colour_puts "<red>failed</red>" | ||
| 144 | |||
| 145 | puts MYSQL_FAILED | ||
| 146 | end | ||
| 147 | |||
| 148 | false | ||
| 149 | end | ||
| 150 | |||
| 151 | # create test db | ||
| 152 | def create_test_database | ||
| 153 | colour_puts "<banner>create test database</banner>" | ||
| 154 | puts | ||
| 155 | |||
| 156 | connect_to_db | ||
| 157 | |||
| 158 | colour_print " * <b>creating thinking_sphinx database</b>... " | ||
| 159 | begin | ||
| 160 | ActiveRecord::Base.connection.create_database('thinking_sphinx') | ||
| 161 | colour_puts "<green>successful</green>" | ||
| 162 | rescue ActiveRecord::StatementInvalid | ||
| 163 | if $!.message[/database exists/] | ||
| 164 | colour_puts "<green>successful</green> (database already existed)" | ||
| 165 | puts | ||
| 166 | return true | ||
| 167 | else | ||
| 168 | colour_puts "<red>failed</red>" | ||
| 169 | end | ||
| 170 | end | ||
| 171 | |||
| 172 | colour_puts CREATE_DATABASE_FAILED | ||
| 173 | |||
| 174 | false | ||
| 175 | end | ||
| 176 | |||
| 177 | # project | ||
| 178 | def ts_root | ||
| 179 | File.expand_path(File.dirname(__FILE__)) | ||
| 180 | end | ||
| 181 | |||
| 182 | def specs | ||
| 183 | ts_root / 'spec' | ||
| 184 | end | ||
| 185 | |||
| 186 | def db_yml | ||
| 187 | specs / 'fixtures' / 'database.yml' | ||
| 188 | end | ||
| 189 | |||
| 190 | def mysql_adapter | ||
| 191 | defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql' | ||
| 192 | end | ||
| 193 | |||
| 194 | def connect_to_db | ||
| 195 | config = YAML.load_file(db_yml) | ||
| 196 | config.update(:adapter => mysql_adapter, :database => 'test') | ||
| 197 | config.symbolize_keys! | ||
| 198 | |||
| 199 | ActiveRecord::Base.establish_connection(config) | ||
| 200 | end | ||
| 201 | end | ||
| 202 | |||
| 203 | |||
| 204 | |||
| 205 | |||
| 206 | |||
| 207 | |||
| 208 | |||
| 209 | class String | ||
| 210 | def /(other) | ||
| 211 | "#{self}/#{other}" | ||
| 212 | end | ||
| 213 | end | ||
| 214 | |||
| 215 | module ContributeHelper | ||
| 216 | class Dependency | ||
| 217 | def self.name(name=nil) | ||
| 218 | if name then @name = name else @name end | ||
| 219 | end | ||
| 220 | |||
| 221 | attr_reader :location | ||
| 222 | |||
| 223 | def initialize | ||
| 224 | @found = false | ||
| 225 | @location = nil | ||
| 226 | end | ||
| 227 | |||
| 228 | def name; self.class.name end | ||
| 229 | |||
| 230 | def check; false end | ||
| 231 | def check! | ||
| 232 | @found = check | ||
| 233 | end | ||
| 234 | |||
| 235 | def found? | ||
| 236 | @found | ||
| 237 | end | ||
| 238 | end | ||
| 239 | |||
| 240 | class Gem < Dependency | ||
| 241 | def gem_name; self.class.name end | ||
| 242 | def name; "#{super} gem" end | ||
| 243 | |||
| 244 | def check | ||
| 245 | ::Gem.available? self.gem_name | ||
| 246 | end | ||
| 247 | end | ||
| 248 | |||
| 249 | |||
| 250 | def check_for_dependencies | ||
| 251 | colour_puts "<banner>Checking for required software</banner>" | ||
| 252 | puts | ||
| 253 | |||
| 254 | all_found = true | ||
| 255 | |||
| 256 | dependencies.each do |klass| | ||
| 257 | dep = klass.new | ||
| 258 | print " * #{dep.name}... " | ||
| 259 | dep.check! | ||
| 260 | |||
| 261 | if dep.found? | ||
| 262 | if dep.location | ||
| 263 | colour_puts "<green>found at #{dep.location}</green>" | ||
| 264 | else | ||
| 265 | colour_puts "<green>found</green>" | ||
| 266 | end | ||
| 267 | else | ||
| 268 | all_found &= false | ||
| 269 | colour_puts "<red>not found</red>" | ||
| 270 | end | ||
| 271 | end | ||
| 272 | |||
| 273 | puts | ||
| 274 | |||
| 275 | all_found | ||
| 276 | end | ||
| 277 | |||
| 278 | |||
| 279 | |||
| 280 | DEFAULT_TERMINAL_COLORS = "\e[0m\e[37m\e[40m" | ||
| 281 | def subs_colour(data) | ||
| 282 | data = data.gsub(%r{<b>(.*?)</b>}m, "\e[1m\\1#{DEFAULT_TERMINAL_COLORS}") | ||
| 283 | data.gsub!(%r{<red>(.*?)</red>}m, "\e[1m\e[31m\\1#{DEFAULT_TERMINAL_COLORS}") | ||
| 284 | data.gsub!(%r{<green>(.*?)</green>}m, "\e[1m\e[32m\\1#{DEFAULT_TERMINAL_COLORS}") | ||
| 285 | data.gsub!(%r{<yellow>(.*?)</yellow>}m, "\e[1m\e[33m\\1#{DEFAULT_TERMINAL_COLORS}") | ||
| 286 | data.gsub!(%r{<banner>(.*?)</banner>}m, "\e[33m\e[44m\e[1m\\1#{DEFAULT_TERMINAL_COLORS}") | ||
| 287 | |||
| 288 | return data | ||
| 289 | end | ||
| 290 | |||
| 291 | def colour_puts(text) | ||
| 292 | puts subs_colour(text) | ||
| 293 | end | ||
| 294 | |||
| 295 | def colour_print(text) | ||
| 296 | print subs_colour(text) | ||
| 297 | end | ||
| 298 | |||
| 299 | |||
| 300 | def wait! | ||
| 301 | colour_puts "<b>Hit Enter to continue, or Ctrl-C to quit.</b>" | ||
| 302 | STDIN.readline | ||
| 303 | rescue Interrupt | ||
| 304 | exit! | ||
| 305 | end | ||
| 306 | end | ||
| 307 | |||
| 308 | module Dependencies | ||
| 309 | class Mysql < ContributeHelper::Gem | ||
| 310 | name(defined?(JRUBY_VERSION) ? 'jdbc-mysql' : 'mysql') | ||
| 311 | end | ||
| 312 | |||
| 313 | class AR < ContributeHelper::Gem | ||
| 314 | name 'activerecord' | ||
| 315 | end | ||
| 316 | |||
| 317 | class Ginger < ContributeHelper::Gem | ||
| 318 | name 'ginger' | ||
| 319 | end | ||
| 320 | |||
| 321 | class Sphinx < ContributeHelper::Dependency | ||
| 322 | name 'sphinx' | ||
| 323 | |||
| 324 | def check | ||
| 325 | output = `which searchd` | ||
| 326 | @location = output.chomp if $? == 0 | ||
| 327 | $? == 0 | ||
| 328 | end | ||
| 329 | end | ||
| 330 | end | ||
| 331 | |||
| 332 | Contribute.new.show \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/cucumber.yml b/vendor/plugins/thinking-sphinx/cucumber.yml new file mode 100644 index 0000000..7a451fe --- /dev/null +++ b/vendor/plugins/thinking-sphinx/cucumber.yml | |||
| @@ -0,0 +1 @@ | |||
| default: "--require features/support/env.rb --require features/support/db/mysql.rb --require features/support/db/active_record.rb --require features/support/post_database.rb --require features/step_definitions/alpha_steps.rb --require features/step_definitions/beta_steps.rb --require features/step_definitions/cat_steps.rb --require features/step_definitions/common_steps.rb --require features/step_definitions/datetime_delta_steps.rb --require features/step_definitions/delayed_delta_indexing_steps.rb --require features/step_definitions/extensible_delta_indexing_steps --require features/step_definitions/facet_steps.rb --require features/step_definitions/find_arguments_steps.rb --require features/step_definitions/gamma_steps.rb --require features/step_definitions/search_steps.rb --require features/step_definitions/sphinx_steps.rb" \ No newline at end of file | |||
diff --git a/vendor/plugins/thinking-sphinx/features/a.rb b/vendor/plugins/thinking-sphinx/features/a.rb new file mode 100644 index 0000000..9f5a14e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/a.rb | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # This file exists because Cucumber likes to auto-load all ruby files | ||
| 2 | puts <<-MESSAGE | ||
| 3 | Cucumber 0.1.12 defaults to loading all ruby files within the features folder | ||
| 4 | alphabetically. This is annoying, because some files need to be loaded before | ||
| 5 | others (and others perhaps not at all, given missing dependencies). Hence this | ||
| 6 | place-holder imaginatively named 'a.rb', to force this message. | ||
| 7 | |||
| 8 | A work-around is to use cucumber profiles. You will find the default profile in | ||
| 9 | cucumber.yml should serve your needs fine, unless you add new step definitions. | ||
| 10 | When you do that, you can regenerate the YAML file by running: | ||
| 11 | rake cucumber_defaults | ||
| 12 | |||
| 13 | And then run specific features as follows is slightly more verbose, but it | ||
| 14 | works, whereas this doesn't. | ||
| 15 | cucumber -p default features/something.feature | ||
| 16 | MESSAGE | ||
| 17 | exit 0 \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/attribute_transformation.feature b/vendor/plugins/thinking-sphinx/features/attribute_transformation.feature new file mode 100644 index 0000000..d987bbd --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/attribute_transformation.feature | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | Feature: Handle not-quite-supported column types as attributes | ||
| 2 | In order for Thinking Sphinx to be more understanding with model structures | ||
| 3 | The plugin | ||
| 4 | Should be able to use translatable columns as attributes | ||
| 5 | |||
| 6 | Scenario: Decimals as floats | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on alphas | ||
| 9 | When I filter between 1.0 and 3.0 on cost | ||
| 10 | Then I should get 2 results | ||
| 11 | |||
| 12 | Scenario: Dates as Datetimes | ||
| 13 | Given Sphinx is running | ||
| 14 | And I am searching on alphas | ||
| 15 | When I filter between 1 and 3 days ago on created_on | ||
| 16 | Then I should get 2 results | ||
| 17 | |||
| 18 | Scenario: Timestamps as Datetimes | ||
| 19 | Given Sphinx is running | ||
| 20 | And I am searching on alphas | ||
| 21 | When I filter between 1 and 3 days ago on created_at | ||
| 22 | Then I should get 2 results \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/datetime_deltas.feature b/vendor/plugins/thinking-sphinx/features/datetime_deltas.feature new file mode 100644 index 0000000..8039c28 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/datetime_deltas.feature | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | Feature: Datetime Delta Indexing | ||
| 2 | In order to have delta indexing on frequently-updated sites | ||
| 3 | Developers | ||
| 4 | Should be able to use an existing datetime column to track changes | ||
| 5 | |||
| 6 | Scenario: Delta Index should not fire automatically | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on thetas | ||
| 9 | When I search for one | ||
| 10 | Then I should get 1 result | ||
| 11 | |||
| 12 | When I change the name of theta one to eleven | ||
| 13 | And I wait for Sphinx to catch up | ||
| 14 | And I search for one | ||
| 15 | Then I should get 1 result | ||
| 16 | |||
| 17 | When I search for eleven | ||
| 18 | Then I should get 0 results | ||
| 19 | |||
| 20 | Scenario: Delta Index should fire when jobs are run | ||
| 21 | Given Sphinx is running | ||
| 22 | And I am searching on thetas | ||
| 23 | When I search for two | ||
| 24 | Then I should get 1 result | ||
| 25 | |||
| 26 | When I change the name of theta two to twelve | ||
| 27 | And I wait for Sphinx to catch up | ||
| 28 | And I search for twelve | ||
| 29 | Then I should get 0 results | ||
| 30 | |||
| 31 | When I index the theta datetime delta | ||
| 32 | And I wait for Sphinx to catch up | ||
| 33 | And I search for twelve | ||
| 34 | Then I should get 1 result | ||
| 35 | |||
| 36 | When I search for two | ||
| 37 | Then I should get 0 results | ||
| 38 | |||
| 39 | Scenario: New records should be merged into the core index | ||
| 40 | Given Sphinx is running | ||
| 41 | And I am searching on thetas | ||
| 42 | When I search for thirteen | ||
| 43 | Then I should get 0 results | ||
| 44 | |||
| 45 | When I create a new theta named thirteen | ||
| 46 | And I search for thirteen | ||
| 47 | Then I should get 0 results | ||
| 48 | |||
| 49 | When I index the theta datetime delta | ||
| 50 | And I wait for Sphinx to catch up | ||
| 51 | And I search for thirteen | ||
| 52 | Then I should get 1 result | ||
| 53 | |||
| 54 | When I search for the document id of theta thirteen in the theta_core index | ||
| 55 | Then it should exist | ||
| 56 | |||
| 57 | Scenario: Deleting records | ||
| 58 | Given Sphinx is running | ||
| 59 | And I am searching on thetas | ||
| 60 | When I search for three | ||
| 61 | Then I should get 1 result | ||
| 62 | |||
| 63 | When I delete the theta named three | ||
| 64 | And I wait for Sphinx to catch up | ||
| 65 | And I search for three | ||
| 66 | Then I should get 0 results | ||
diff --git a/vendor/plugins/thinking-sphinx/features/delayed_delta_indexing.feature b/vendor/plugins/thinking-sphinx/features/delayed_delta_indexing.feature new file mode 100644 index 0000000..5be4c4e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/delayed_delta_indexing.feature | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | Feature: Delayed Delta Indexing | ||
| 2 | In order to have delta indexing on frequently-updated sites | ||
| 3 | Developers | ||
| 4 | Should be able to use delayed_job to handle delta indexes to lower system load | ||
| 5 | |||
| 6 | Scenario: Delta Index should not fire automatically | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on delayed betas | ||
| 9 | When I search for one | ||
| 10 | Then I should get 1 result | ||
| 11 | |||
| 12 | When I change the name of delayed beta one to eleven | ||
| 13 | And I wait for Sphinx to catch up | ||
| 14 | And I search for one | ||
| 15 | Then I should get 1 result | ||
| 16 | |||
| 17 | When I search for eleven | ||
| 18 | Then I should get 0 results | ||
| 19 | |||
| 20 | Scenario: Delta Index should fire when jobs are run | ||
| 21 | Given Sphinx is running | ||
| 22 | And I am searching on delayed betas | ||
| 23 | When I search for one | ||
| 24 | Then I should get 1 result | ||
| 25 | |||
| 26 | When I change the name of delayed beta two to twelve | ||
| 27 | And I wait for Sphinx to catch up | ||
| 28 | And I search for twelve | ||
| 29 | Then I should get 0 results | ||
| 30 | |||
| 31 | When I run the delayed jobs | ||
| 32 | And I wait for Sphinx to catch up | ||
| 33 | And I search for twelve | ||
| 34 | Then I should get 1 result | ||
| 35 | |||
| 36 | When I search for two | ||
| 37 | Then I should get 0 results \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/deleting_instances.feature b/vendor/plugins/thinking-sphinx/features/deleting_instances.feature new file mode 100644 index 0000000..7080a0b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/deleting_instances.feature | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | Feature: Keeping Sphinx in line with deleted model instances | ||
| 2 | In order to avoid deleted items being returned by Sphinx | ||
| 3 | Thinking Sphinx | ||
| 4 | Should keep deleted items out of search results | ||
| 5 | |||
| 6 | Scenario: Deleting instances from the core index | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on betas | ||
| 9 | When I search for three | ||
| 10 | Then I should get 1 result | ||
| 11 | |||
| 12 | When I destroy beta three | ||
| 13 | And I wait for Sphinx to catch up | ||
| 14 | And I search for three | ||
| 15 | Then I should get 0 results | ||
| 16 | |||
| 17 | Scenario: Deleting subclasses when the parent class is indexed | ||
| 18 | Given Sphinx is running | ||
| 19 | And I am searching on cats | ||
| 20 | When I search for moggy | ||
| 21 | Then I should get 1 result | ||
| 22 | |||
| 23 | When I destroy cat moggy | ||
| 24 | And I wait for Sphinx to catch up | ||
| 25 | And I search for moggy | ||
| 26 | Then I should get 0 results | ||
| 27 | |||
| 28 | Scenario: Deleting created instances from the delta index | ||
| 29 | Given Sphinx is running | ||
| 30 | And I am searching on betas | ||
| 31 | When I create a new beta named eleven | ||
| 32 | And I wait for Sphinx to catch up | ||
| 33 | And I search for eleven | ||
| 34 | Then I should get 1 result | ||
| 35 | |||
| 36 | When I destroy beta eleven | ||
| 37 | And I wait for Sphinx to catch up | ||
| 38 | And I search for eleven | ||
| 39 | Then I should get 0 results | ||
| 40 | |||
| 41 | Scenario: Deleting edited instances from the delta index | ||
| 42 | Given Sphinx is running | ||
| 43 | And I am searching on betas | ||
| 44 | When I change the name of beta four to fourteen | ||
| 45 | And I wait for Sphinx to catch up | ||
| 46 | And I search for fourteen | ||
| 47 | Then I should get 1 result | ||
| 48 | |||
| 49 | When I destroy beta fourteen | ||
| 50 | And I wait for Sphinx to catch up | ||
| 51 | And I search for fourteen | ||
| 52 | Then I should get 0 results | ||
diff --git a/vendor/plugins/thinking-sphinx/features/extensible_delta_indexing.feature b/vendor/plugins/thinking-sphinx/features/extensible_delta_indexing.feature new file mode 100644 index 0000000..b06ce6a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/extensible_delta_indexing.feature | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | Feature: Delayed Delta Indexing | ||
| 2 | In order to have delta indexing on frequently-updated sites | ||
| 3 | Developers | ||
| 4 | Should be able to create their own handlers for delta indexing | ||
| 5 | |||
| 6 | Scenario: I specify a valid handler for delta indexing | ||
| 7 | Given Sphinx is running | ||
| 8 | When I change the name of extensible beta one to eleven | ||
| 9 | Then the generic delta handler should handle the delta indexing \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/facets.feature b/vendor/plugins/thinking-sphinx/features/facets.feature new file mode 100644 index 0000000..8788ab4 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/facets.feature | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | Feature: Search and browse models by their defined facets | ||
| 2 | |||
| 3 | Scenario: Requesting facets | ||
| 4 | Given Sphinx is running | ||
| 5 | And I am searching on developers | ||
| 6 | When I am requesting facet results | ||
| 7 | Then I should have valid facet results | ||
| 8 | And I should have 5 facets | ||
| 9 | And I should have the facet State | ||
| 10 | And I should have the facet Country | ||
| 11 | And I should have the facet Age | ||
| 12 | And I should have the facet City | ||
| 13 | And I should have the facet Tag Ids | ||
| 14 | |||
| 15 | Scenario: Requesting facet results | ||
| 16 | Given Sphinx is running | ||
| 17 | And I am searching on developers | ||
| 18 | When I am requesting facet results | ||
| 19 | And I drill down where Country is Australia | ||
| 20 | Then I should get 11 results | ||
| 21 | |||
| 22 | Scenario: Requesting facet results by multiple facets | ||
| 23 | Given Sphinx is running | ||
| 24 | And I am searching on developers | ||
| 25 | When I am requesting facet results | ||
| 26 | And I drill down where Country is Australia and Age is 30 | ||
| 27 | Then I should get 4 results | ||
| 28 | |||
| 29 | Scenario: Requesting facets with classes included | ||
| 30 | Given Sphinx is running | ||
| 31 | And I am searching on developers | ||
| 32 | When I am requesting facet results | ||
| 33 | And I want classes included | ||
| 34 | Then I should have valid facet results | ||
| 35 | And I should have 6 facets | ||
| 36 | And I should have the facet Class | ||
| 37 | |||
| 38 | Scenario: Requesting MVA facets | ||
| 39 | Given Sphinx is running | ||
| 40 | And I am searching on developers | ||
| 41 | When I am requesting facet results | ||
| 42 | And I drill down where tag_ids includes the id of tag Australia | ||
| 43 | Then I should get 11 results | ||
| 44 | When I am requesting facet results | ||
| 45 | And I drill down where tag_ids includes the id of tags Melbourne or Sydney | ||
| 46 | Then I should get 5 results | ||
diff --git a/vendor/plugins/thinking-sphinx/features/facets_across_model.feature b/vendor/plugins/thinking-sphinx/features/facets_across_model.feature new file mode 100644 index 0000000..a218601 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/facets_across_model.feature | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | Feature: Search and browse across models by their defined facets | ||
| 2 | |||
| 3 | Scenario: Requesting facets across multiple models | ||
| 4 | Given Sphinx is running | ||
| 5 | When I am requesting facet results | ||
| 6 | And I want all possible attributes | ||
| 7 | Then I should have valid facet results | ||
| 8 | And I should have 8 facets | ||
| 9 | And I should have the facet Class | ||
| 10 | And the Class facet should have a "Person" key | ||
| 11 | And I should have the facet Gender | ||
| 12 | And the Gender facet should have a "female" key | ||
| 13 | And I should have the facet Country | ||
| 14 | And I should have the facet Category Name | ||
| 15 | And the Category Name facet should have a "hello" key with 10 hits | ||
| 16 | |||
| 17 | Scenario: Requesting facets across models without class results | ||
| 18 | Given Sphinx is running | ||
| 19 | When I am requesting facet results | ||
| 20 | And I want all possible attributes | ||
| 21 | And I don't want classes included | ||
| 22 | Then I should have 7 facets | ||
| 23 | And I should not have the facet Class | ||
diff --git a/vendor/plugins/thinking-sphinx/features/handling_edits.feature b/vendor/plugins/thinking-sphinx/features/handling_edits.feature new file mode 100644 index 0000000..6b14766 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/handling_edits.feature | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | Feature: Keeping Sphinx in line with model changes when requested | ||
| 2 | In order to keep indexes as up to date as possible | ||
| 3 | Thinking Sphinx | ||
| 4 | Should return the expected results depending on whether delta indexes are used | ||
| 5 | |||
| 6 | Scenario: Returning instance from old data if there is no delta | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on alphas | ||
| 9 | When I search for two | ||
| 10 | Then I should get 1 result | ||
| 11 | |||
| 12 | When I change the name of alpha two to twelve | ||
| 13 | And I wait for Sphinx to catch up | ||
| 14 | And I search for two | ||
| 15 | Then I should get 1 result | ||
| 16 | |||
| 17 | Scenario: Not returing an instance from old data if there is a delta | ||
| 18 | Given Sphinx is running | ||
| 19 | And I am searching on betas | ||
| 20 | When I search for two | ||
| 21 | Then I should get 1 result | ||
| 22 | |||
| 23 | When I change the name of beta two to twelve | ||
| 24 | And I wait for Sphinx to catch up | ||
| 25 | And I search for two | ||
| 26 | Then I should get 0 results | ||
| 27 | |||
| 28 | Scenario: Returning instance from new data if there is a delta | ||
| 29 | Given Sphinx is running | ||
| 30 | And I am searching on betas | ||
| 31 | When I search for one | ||
| 32 | Then I should get 1 result | ||
| 33 | |||
| 34 | When I change the name of beta one to eleven | ||
| 35 | And I wait for Sphinx to catch up | ||
| 36 | And I search for one | ||
| 37 | Then I should get 0 results | ||
| 38 | |||
| 39 | When I search for eleven | ||
| 40 | Then I should get 1 result | ||
| 41 | |||
| 42 | Scenario: Returning new records if there's a delta | ||
| 43 | Given Sphinx is running | ||
| 44 | And I am searching on betas | ||
| 45 | When I search for fifteen | ||
| 46 | Then I should get 0 results | ||
| 47 | |||
| 48 | When I create a new beta named fifteen | ||
| 49 | And I wait for Sphinx to catch up | ||
| 50 | And I search for fifteen | ||
| 51 | Then I should get 1 result | ||
| 52 | |||
| 53 | Scenario: Avoiding delta updates if there hasn't been changes | ||
| 54 | Given Sphinx is running | ||
| 55 | And I am searching on betas | ||
| 56 | When I search for five | ||
| 57 | Then I should get 1 result | ||
| 58 | |||
| 59 | When I change the name of beta five to five | ||
| 60 | And I wait for Sphinx to catch up | ||
| 61 | And I search for five | ||
| 62 | Then I should get 1 result | ||
| 63 | |||
| 64 | When I search for the document id of beta five in the beta_core index | ||
| 65 | Then it should exist if using Rails 2.1 or newer | ||
| 66 | When I search for the document id of beta five in the beta_delta index | ||
| 67 | Then it should not exist if using Rails 2.1 or newer | ||
| 68 | |||
| 69 | Scenario: Handling edits with a delta when Sphinx isn't running | ||
| 70 | Given Sphinx is running | ||
| 71 | And I am searching on betas | ||
| 72 | When I stop Sphinx | ||
| 73 | And I change the name of beta six to sixteen | ||
| 74 | And I start Sphinx | ||
| 75 | And I search for sixteen | ||
| 76 | Then I should get 1 result | ||
diff --git a/vendor/plugins/thinking-sphinx/features/retry_stale_indexes.feature b/vendor/plugins/thinking-sphinx/features/retry_stale_indexes.feature new file mode 100644 index 0000000..a14f43a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/retry_stale_indexes.feature | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | Feature: Manually updating Sphinx indexes to handle uncaught deletions | ||
| 2 | In order to keep indexes as up to date as possible | ||
| 3 | Thinking Sphinx | ||
| 4 | Should automatically update the indexes and retry the search if it gets a nil result | ||
| 5 | |||
| 6 | Scenario: Changing retry_stale settings | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on gammas | ||
| 9 | Then I should not get 0 results | ||
| 10 | |||
| 11 | When I set retry stale to false | ||
| 12 | And I set per page to 1 | ||
| 13 | And I order by "sphinx_internal_id ASC" | ||
| 14 | And I destroy gamma one without callbacks | ||
| 15 | Then I should get a single result of nil | ||
| 16 | |||
| 17 | When I set retry stale to 1 | ||
| 18 | Then I should get a single gamma result with a name of two | ||
| 19 | |||
| 20 | When I destroy gamma two without callbacks | ||
| 21 | Then I should get a single result of nil | ||
| 22 | |||
| 23 | When I set retry stale to true | ||
| 24 | Then I should get a single gamma result with a name of three | ||
diff --git a/vendor/plugins/thinking-sphinx/features/searching_across_models.feature b/vendor/plugins/thinking-sphinx/features/searching_across_models.feature new file mode 100644 index 0000000..50f5933 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/searching_across_models.feature | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | Feature: Searching across multiple model | ||
| 2 | In order to use Thinking Sphinx's core functionality | ||
| 3 | A developer | ||
| 4 | Should be able to search on multiple models | ||
| 5 | |||
| 6 | Scenario: Retrieving total result count | ||
| 7 | Given Sphinx is running | ||
| 8 | When I search for James | ||
| 9 | And I am retrieving the result count | ||
| 10 | Then I should get a value of 3 | ||
| 11 | |||
| 12 | Scenario: Confirming existance of a document id in a given index | ||
| 13 | Given Sphinx is running | ||
| 14 | When I search for the document id of alpha one in the alpha_core index | ||
| 15 | Then it should exist | ||
| 16 | |||
| 17 | Scenario: Retrieving results from multiple models | ||
| 18 | Given Sphinx is running | ||
| 19 | When I search for ten | ||
| 20 | Then I should get 6 results | ||
diff --git a/vendor/plugins/thinking-sphinx/features/searching_by_model.feature b/vendor/plugins/thinking-sphinx/features/searching_by_model.feature new file mode 100644 index 0000000..2e482e4 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/searching_by_model.feature | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | Feature: Searching on a single model | ||
| 2 | In order to use Thinking Sphinx's core functionality | ||
| 3 | A developer | ||
| 4 | Should be able to search on a single model | ||
| 5 | |||
| 6 | Scenario: Searching using a basic query | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on people | ||
| 9 | When I search for James | ||
| 10 | Then I should get 3 results | ||
| 11 | |||
| 12 | Scenario: Searching on a specific field | ||
| 13 | Given Sphinx is running | ||
| 14 | And I am searching on people | ||
| 15 | When I search for James on first_name | ||
| 16 | Then I should get 2 results | ||
| 17 | |||
| 18 | Scenario: Searching on multiple fields | ||
| 19 | Given Sphinx is running | ||
| 20 | And I am searching on people | ||
| 21 | When I search for James on first_name | ||
| 22 | And I search for Chamberlain on last_name | ||
| 23 | Then I should get 1 result | ||
| 24 | |||
| 25 | Scenario: Searching on association content | ||
| 26 | Given Sphinx is running | ||
| 27 | And I am searching on posts | ||
| 28 | |||
| 29 | When I search for "Waffles" | ||
| 30 | Then I should get 1 result | ||
| 31 | |||
| 32 | When I search for "Turtle" | ||
| 33 | Then I should get 1 result | ||
| 34 | |||
| 35 | Scenario: Searching with a filter | ||
| 36 | Given Sphinx is running | ||
| 37 | And I am searching on alphas | ||
| 38 | When I filter by 1 on value | ||
| 39 | Then I should get 1 result | ||
| 40 | |||
| 41 | Scenario: Searching with multiple filters | ||
| 42 | Given Sphinx is running | ||
| 43 | And I am searching on boxes | ||
| 44 | When I filter by 2 on width | ||
| 45 | And I filter by 2 on length | ||
| 46 | Then I should get 1 result | ||
| 47 | |||
| 48 | Scenario: Searching to filter multiple values on an MVA | ||
| 49 | Given Sphinx is running | ||
| 50 | And I am searching on boxes | ||
| 51 | When I filter by 11 and 12 on dimensions | ||
| 52 | Then I should get 2 results | ||
| 53 | When I clear existing filters | ||
| 54 | And I filter by both 11 and 12 on dimensions | ||
| 55 | Then I should get 1 result | ||
| 56 | |||
| 57 | Scenario: Searching on a MVA configured as ranged_query | ||
| 58 | Given Sphinx is running | ||
| 59 | And I am searching on posts | ||
| 60 | When I filter by 1 on comment_ids | ||
| 61 | Then I should get 1 result | ||
| 62 | When I clear existing filters | ||
| 63 | And I filter by both 1 and 2 on comment_ids | ||
| 64 | Then I should get 1 results | ||
| 65 | When I clear existing filters | ||
| 66 | And I filter by 10 on comment_ids | ||
| 67 | Then I should get 0 results | ||
| 68 | |||
| 69 | Scenario: Searching with ordering by attribute | ||
| 70 | Given Sphinx is running | ||
| 71 | And I am searching on alphas | ||
| 72 | When I order by value | ||
| 73 | Then I should get 10 results | ||
| 74 | And the value of each result should indicate order | ||
| 75 | |||
| 76 | Scenario: Searching with ordering on a sortable field | ||
| 77 | Given Sphinx is running | ||
| 78 | And I am searching on people | ||
| 79 | And I order by first_name | ||
| 80 | Then I should get 20 results | ||
| 81 | And the first_name of each result should indicate order | ||
| 82 | |||
| 83 | Scenario: Intepreting Sphinx Internal Identifiers | ||
| 84 | Given Sphinx is running | ||
| 85 | And I am searching on people | ||
| 86 | Then I should get 20 results | ||
| 87 | And each result id should match the corresponding sphinx internal id | ||
| 88 | |||
| 89 | Scenario: Retrieving weightings | ||
| 90 | Given Sphinx is running | ||
| 91 | And I am searching on people | ||
| 92 | When I search for "Ellie Ford" | ||
| 93 | And I set match mode to any | ||
| 94 | Then I can iterate by result and weighting | ||
| 95 | |||
| 96 | Scenario: Retrieving group counts | ||
| 97 | Given Sphinx is running | ||
| 98 | And I am searching on people | ||
| 99 | When I group results by the birthday attribute | ||
| 100 | Then I can iterate by result and count | ||
| 101 | |||
| 102 | Scenario: Retrieving group values | ||
| 103 | Given Sphinx is running | ||
| 104 | And I am searching on people | ||
| 105 | When I group results by the birthday attribute | ||
| 106 | Then I can iterate by result and group | ||
| 107 | |||
| 108 | Scenario: Retrieving both group values and counts | ||
| 109 | Given Sphinx is running | ||
| 110 | And I am searching on people | ||
| 111 | When I group results by the birthday attribute | ||
| 112 | Then I can iterate by result and group and count | ||
| 113 | |||
| 114 | Scenario: Searching for ids | ||
| 115 | Given Sphinx is running | ||
| 116 | And I am searching on people | ||
| 117 | When I search for Ellie | ||
| 118 | And I am searching for ids | ||
| 119 | Then I should have an array of integers | ||
| 120 | |||
| 121 | Scenario: Search results should match Sphinx's order | ||
| 122 | Given Sphinx is running | ||
| 123 | And I am searching on people | ||
| 124 | When I search for Ellie | ||
| 125 | And I order by "sphinx_internal_id DESC" | ||
| 126 | Then searching for ids should match the record ids of the normal search results | ||
| 127 | |||
| 128 | Scenario: Retrieving total result count when total is less than a page | ||
| 129 | Given Sphinx is running | ||
| 130 | And I am searching on people | ||
| 131 | When I search for James | ||
| 132 | And I am retrieving the result count | ||
| 133 | Then I should get a value of 3 | ||
| 134 | |||
| 135 | Scenario: Retrieving total result count for more than a page | ||
| 136 | Given Sphinx is running | ||
| 137 | And I am searching on people | ||
| 138 | When I am retrieving the result count | ||
| 139 | Then I should get a value of 1000 | ||
| 140 | \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/searching_with_find_arguments.feature b/vendor/plugins/thinking-sphinx/features/searching_with_find_arguments.feature new file mode 100644 index 0000000..68a5bb9 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/searching_with_find_arguments.feature | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | Feature: Keeping AR::Base.find arguments in search calls | ||
| 2 | To keep things as streamlined as possible | ||
| 3 | Thinking Sphinx | ||
| 4 | Should respect particular arguments to AR::Base.find calls | ||
| 5 | |||
| 6 | Scenario: Respecting the include option | ||
| 7 | Given Sphinx is running | ||
| 8 | And I am searching on posts | ||
| 9 | Then I should get 1 result | ||
| 10 | |||
| 11 | When I get the first comment | ||
| 12 | And I track queries | ||
| 13 | And I compare comments | ||
| 14 | Then I should have 1 query | ||
| 15 | |||
| 16 | When I include comments | ||
| 17 | Then I should get 1 result | ||
| 18 | When I track queries | ||
| 19 | And I compare comments | ||
| 20 | Then I should have 0 queries | ||
| 21 | |||
| 22 | Scenario: Respecting the include option without using a specific model | ||
| 23 | Given Sphinx is running | ||
| 24 | And I search for "Hello World" | ||
| 25 | Then I should get 1 result | ||
| 26 | |||
| 27 | When I get the first comment | ||
| 28 | And I track queries | ||
| 29 | And I compare comments | ||
| 30 | Then I should have 1 query | ||
| 31 | |||
| 32 | When I include comments | ||
| 33 | Then I should get 1 result | ||
| 34 | When I track queries | ||
| 35 | And I compare comments | ||
| 36 | Then I should have 0 queries | ||
| 37 | |||
| 38 | Scenario: Respecting the select option | ||
| 39 | Given Sphinx is running | ||
| 40 | And I am searching on posts | ||
| 41 | Then I should get 1 result | ||
| 42 | And I should not get an error accessing the subject | ||
| 43 | |||
| 44 | When I select only content | ||
| 45 | Then I should get 1 result | ||
| 46 | And I should get an error accessing the subject | ||
| 47 | |||
| 48 | Scenario: Respecting the select option without using a specific model | ||
| 49 | Given Sphinx is running | ||
| 50 | When I search for "Hello World" | ||
| 51 | Then I should get 1 result | ||
| 52 | And I should not get an error accessing the subject | ||
| 53 | |||
| 54 | When I select only content | ||
| 55 | Then I should get 1 result | ||
| 56 | And I should get an error accessing the subject \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/sphinx_detection.feature b/vendor/plugins/thinking-sphinx/features/sphinx_detection.feature new file mode 100644 index 0000000..ebe431e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/sphinx_detection.feature | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | Feature: Checking whether Sphinx is running or not | ||
| 2 | In order to avoid unnecessary errors | ||
| 3 | Thinking Sphinx | ||
| 4 | Should be able to determine whether Sphinx is running or not | ||
| 5 | |||
| 6 | Scenario: Checking Sphinx's status | ||
| 7 | Given Sphinx is running | ||
| 8 | Then Sphinx should be running | ||
| 9 | |||
| 10 | When I stop Sphinx | ||
| 11 | And I wait for Sphinx to catch up | ||
| 12 | Then Sphinx should not be running | ||
| 13 | |||
| 14 | When I start Sphinx | ||
| 15 | And I wait for Sphinx to catch up | ||
| 16 | Then Sphinx should be running | ||
| 17 | |||
| 18 | Given Sphinx is running | ||
| 19 | When I kill the Sphinx process | ||
| 20 | And I wait for Sphinx to catch up | ||
| 21 | Then Sphinx should not be running \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/alpha_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/alpha_steps.rb new file mode 100644 index 0000000..987b10b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/alpha_steps.rb | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | When /^I change the name of alpha (\w+) to (\w+)$/ do |current, replacement| | ||
| 2 | Alpha.find_by_name(current).update_attributes(:name => replacement) | ||
| 3 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/beta_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/beta_steps.rb new file mode 100644 index 0000000..2d566a1 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/beta_steps.rb | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | When /^I destroy beta (\w+)$/ do |name| | ||
| 2 | Beta.find_by_name(name).destroy | ||
| 3 | end | ||
| 4 | |||
| 5 | When /^I create a new beta named (\w+)$/ do |name| | ||
| 6 | Beta.create(:name => name) | ||
| 7 | end | ||
| 8 | |||
| 9 | When /^I change the name of beta (\w+) to (\w+)$/ do |current, replacement| | ||
| 10 | Beta.find_by_name(current).update_attributes(:name => replacement) | ||
| 11 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/cat_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/cat_steps.rb new file mode 100644 index 0000000..82b8b7f --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/cat_steps.rb | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | When /^I destroy cat (\w+)$/ do |name| | ||
| 2 | Cat.find_by_name(name).destroy | ||
| 3 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/common_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/common_steps.rb new file mode 100644 index 0000000..de45a20 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/common_steps.rb | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | Before do | ||
| 2 | $queries_executed = [] | ||
| 3 | ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs | ||
| 4 | |||
| 5 | @model = nil | ||
| 6 | @method = :search | ||
| 7 | @query = "" | ||
| 8 | @conditions = {} | ||
| 9 | @with = {} | ||
| 10 | @without = {} | ||
| 11 | @with_all = {} | ||
| 12 | @options = {} | ||
| 13 | end | ||
| 14 | |||
| 15 | Given /^I am searching on (.+)$/ do |model| | ||
| 16 | @model = model.gsub(/\s/, '_').singularize.camelize.constantize | ||
| 17 | end | ||
| 18 | |||
| 19 | When /^I am searching for ids$/ do | ||
| 20 | @results = nil | ||
| 21 | @method = :search_for_ids | ||
| 22 | end | ||
| 23 | |||
| 24 | When /^I am retrieving the result count$/ do | ||
| 25 | @result = nil | ||
| 26 | @method = @model ? :search_count : :count | ||
| 27 | end | ||
| 28 | |||
| 29 | When /^I search for (\w+)$/ do |query| | ||
| 30 | @results = nil | ||
| 31 | @query = query | ||
| 32 | end | ||
| 33 | |||
| 34 | When /^I search for "([^\"]+)"$/ do |query| | ||
| 35 | @results = nil | ||
| 36 | @query = query | ||
| 37 | end | ||
| 38 | |||
| 39 | When /^I search for (\w+) on (\w+)$/ do |query, field| | ||
| 40 | @results = nil | ||
| 41 | @conditions[field.to_sym] = query | ||
| 42 | end | ||
| 43 | |||
| 44 | When /^I clear existing filters$/ do | ||
| 45 | @with = {} | ||
| 46 | @without = {} | ||
| 47 | @with_all = {} | ||
| 48 | end | ||
| 49 | |||
| 50 | When /^I filter by (\w+) on (\w+)$/ do |filter, attribute| | ||
| 51 | @results = nil | ||
| 52 | @with[attribute.to_sym] = filter.to_i | ||
| 53 | end | ||
| 54 | |||
| 55 | When /^I filter by (\d+) and (\d+) on (\w+)$/ do |value_one, value_two, attribute| | ||
| 56 | @results = nil | ||
| 57 | @with[attribute.to_sym] = [value_one.to_i, value_two.to_i] | ||
| 58 | end | ||
| 59 | |||
| 60 | When /^I filter by both (\d+) and (\d+) on (\w+)$/ do |value_one, value_two, attribute| | ||
| 61 | @results = nil | ||
| 62 | @with_all[attribute.to_sym] = [value_one.to_i, value_two.to_i] | ||
| 63 | end | ||
| 64 | |||
| 65 | When /^I filter between ([\d\.]+) and ([\d\.]+) on (\w+)$/ do |first, last, attribute| | ||
| 66 | @results = nil | ||
| 67 | if first[/\./].nil? && last[/\./].nil? | ||
| 68 | @with[attribute.to_sym] = first.to_i..last.to_i | ||
| 69 | else | ||
| 70 | @with[attribute.to_sym] = first.to_f..last.to_f | ||
| 71 | end | ||
| 72 | end | ||
| 73 | |||
| 74 | When /^I filter between (\d+) and (\d+) days ago on (\w+)$/ do |last, first, attribute| | ||
| 75 | @results = nil | ||
| 76 | @with[attribute.to_sym] = first.to_i.days.ago..last.to_i.days.ago | ||
| 77 | end | ||
| 78 | |||
| 79 | When /^I order by (\w+)$/ do |attribute| | ||
| 80 | @results = nil | ||
| 81 | @options[:order] = attribute.to_sym | ||
| 82 | end | ||
| 83 | |||
| 84 | When /^I order by "([^\"]+)"$/ do |str| | ||
| 85 | @results = nil | ||
| 86 | @options[:order] = str | ||
| 87 | end | ||
| 88 | |||
| 89 | When /^I group results by the (\w+) attribute$/ do |attribute| | ||
| 90 | @results = nil | ||
| 91 | @options[:group_function] = :attr | ||
| 92 | @options[:group_by] = attribute | ||
| 93 | end | ||
| 94 | |||
| 95 | When /^I set match mode to (\w+)$/ do |match_mode| | ||
| 96 | @results = nil | ||
| 97 | @options[:match_mode] = match_mode.to_sym | ||
| 98 | end | ||
| 99 | |||
| 100 | When /^I set per page to (\d+)$/ do |per_page| | ||
| 101 | @results = nil | ||
| 102 | @options[:per_page] = per_page.to_i | ||
| 103 | end | ||
| 104 | |||
| 105 | When /^I set retry stale to (\w+)$/ do |retry_stale| | ||
| 106 | @results = nil | ||
| 107 | @options[:retry_stale] = case retry_stale | ||
| 108 | when "true" then true | ||
| 109 | when "false" then false | ||
| 110 | else retry_stale.to_i | ||
| 111 | end | ||
| 112 | end | ||
| 113 | |||
| 114 | Then /^the (\w+) of each result should indicate order$/ do |attribute| | ||
| 115 | results.inject(nil) do |prev, current| | ||
| 116 | unless prev.nil? | ||
| 117 | current.send(attribute.to_sym).should >= prev.send(attribute.to_sym) | ||
| 118 | end | ||
| 119 | |||
| 120 | current | ||
| 121 | end | ||
| 122 | end | ||
| 123 | |||
| 124 | Then /^I can iterate by result and (\w+)$/ do |attribute| | ||
| 125 | iteration = lambda { |result, attr_value| | ||
| 126 | result.should be_kind_of(@model) | ||
| 127 | unless attribute == "group" && attr_value.nil? | ||
| 128 | attr_value.should be_kind_of(Integer) | ||
| 129 | end | ||
| 130 | } | ||
| 131 | |||
| 132 | results.send("each_with_#{attribute}", &iteration) | ||
| 133 | end | ||
| 134 | |||
| 135 | Then /^I should get (\d+) results?$/ do |count| | ||
| 136 | results.length.should == count.to_i | ||
| 137 | end | ||
| 138 | |||
| 139 | Then /^I should not get (\d+) results?$/ do |count| | ||
| 140 | results.length.should_not == count.to_i | ||
| 141 | end | ||
| 142 | |||
| 143 | def results | ||
| 144 | @results ||= (@model || ThinkingSphinx::Search).send( | ||
| 145 | @method, | ||
| 146 | @query, | ||
| 147 | @options.merge( | ||
| 148 | :conditions => @conditions, | ||
| 149 | :with => @with, | ||
| 150 | :without => @without, | ||
| 151 | :with_all => @with_all | ||
| 152 | ) | ||
| 153 | ) | ||
| 154 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/datetime_delta_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/datetime_delta_steps.rb new file mode 100644 index 0000000..b1d87fe --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/datetime_delta_steps.rb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | When /^I index the theta datetime delta$/ do | ||
| 2 | Theta.sphinx_indexes.first.delta_object.delayed_index(Theta) | ||
| 3 | end | ||
| 4 | |||
| 5 | When /^I change the name of theta (\w+) to (\w+)$/ do |current, replacement| | ||
| 6 | Theta.find_by_name(current).update_attributes(:name => replacement) | ||
| 7 | end | ||
| 8 | |||
| 9 | When /^I create a new theta named (\w+)$/ do |name| | ||
| 10 | Theta.create(:name => name) | ||
| 11 | end | ||
| 12 | |||
| 13 | When /^I delete the theta named (\w+)$/ do |name| | ||
| 14 | Theta.find_by_name(name).destroy | ||
| 15 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/delayed_delta_indexing_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/delayed_delta_indexing_steps.rb new file mode 100644 index 0000000..dc30ee5 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/delayed_delta_indexing_steps.rb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | When /^I run the delayed jobs$/ do | ||
| 2 | Delayed::Job.work_off.inspect | ||
| 3 | end | ||
| 4 | |||
| 5 | When /^I change the name of delayed beta (\w+) to (\w+)$/ do |current, replacement| | ||
| 6 | DelayedBeta.find_by_name(current).update_attributes(:name => replacement) | ||
| 7 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/extensible_delta_indexing_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/extensible_delta_indexing_steps.rb new file mode 100644 index 0000000..472e112 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/extensible_delta_indexing_steps.rb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | When /I change the name of extensible beta (\w+) to (\w+)$/ do |current, replacement| | ||
| 2 | ExtensibleBeta.find_by_name(current).update_attributes(:name => replacement) | ||
| 3 | end | ||
| 4 | |||
| 5 | Then /^the generic delta handler should handle the delta indexing$/ do | ||
| 6 | ExtensibleBeta.find(:first, :conditions => {:changed_by_generic => true}).should_not be_nil | ||
| 7 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/facet_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/facet_steps.rb new file mode 100644 index 0000000..b788529 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/facet_steps.rb | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | When "I am requesting facet results$" do | ||
| 2 | @results = nil | ||
| 3 | @method = :facets | ||
| 4 | end | ||
| 5 | |||
| 6 | When "I want classes included" do | ||
| 7 | @options[:class_facet] = true | ||
| 8 | end | ||
| 9 | |||
| 10 | When "I don't want classes included" do | ||
| 11 | @options[:class_facet] = false | ||
| 12 | end | ||
| 13 | |||
| 14 | When "I want all possible attributes" do | ||
| 15 | @options[:all_attributes] = true | ||
| 16 | end | ||
| 17 | |||
| 18 | When /^I drill down where (\w+) is (\w+)$/ do |facet, value| | ||
| 19 | @results = results.for(facet.downcase.to_sym => value) | ||
| 20 | end | ||
| 21 | |||
| 22 | When /^I drill down where (\w+) is (\w+) and (\w+) is (\w+)$/ do |facet_one, value_one, facet_two, value_two| | ||
| 23 | value_one = value_one.to_i unless value_one[/^\d+$/].nil? | ||
| 24 | value_two = value_two.to_i unless value_two[/^\d+$/].nil? | ||
| 25 | |||
| 26 | @results = results.for( | ||
| 27 | facet_one.downcase.to_sym => value_one, | ||
| 28 | facet_two.downcase.to_sym => value_two | ||
| 29 | ) | ||
| 30 | end | ||
| 31 | |||
| 32 | When /^I drill down where ([\w_]+) includes the id of tag (\w+)$/ do |facet, text| | ||
| 33 | tag = Tag.find_by_text(text) | ||
| 34 | @results = results.for(facet.downcase.to_sym => tag.id) | ||
| 35 | end | ||
| 36 | |||
| 37 | When /^I drill down where ([\w_]+) includes the id of tags (\w+) or (\w+)$/ do |facet, text_one, text_two| | ||
| 38 | tag_one = Tag.find_by_text(text_one) | ||
| 39 | tag_two = Tag.find_by_text(text_two) | ||
| 40 | @results = results.for(facet.downcase.to_sym => [tag_one.id, tag_two.id]) | ||
| 41 | end | ||
| 42 | |||
| 43 | Then "I should have valid facet results" do | ||
| 44 | results.should be_kind_of(Hash) | ||
| 45 | results.values.each { |value| value.should be_kind_of(Hash) } | ||
| 46 | end | ||
| 47 | |||
| 48 | Then /^I should have (\d+) facets?$/ do |count| | ||
| 49 | results.keys.length.should == count.to_i | ||
| 50 | end | ||
| 51 | |||
| 52 | Then /^I should have the facet ([\w_\s]+)$/ do |name| | ||
| 53 | results[facet_name(name)].should be_kind_of(Hash) | ||
| 54 | end | ||
| 55 | |||
| 56 | Then /^I should not have the facet ([\w_\s]+)$/ do |name| | ||
| 57 | results.keys.should_not include(facet_name(name)) | ||
| 58 | end | ||
| 59 | |||
| 60 | Then /^the ([\w_\s]+) facet should have a "([\w\s_]+)" key with (\d+) hits$/ do |name, key, hit_count| | ||
| 61 | facet_name = facet_name name | ||
| 62 | results[facet_name].keys.should include(key) | ||
| 63 | results[facet_name][key].should eql(hit_count.to_i) | ||
| 64 | end | ||
| 65 | |||
| 66 | Then /^the ([\w_\s]+) facet should have a "(\w+)" key$/ do |name, key| | ||
| 67 | results[facet_name(name)].keys.should include(key) | ||
| 68 | end | ||
| 69 | |||
| 70 | def facet_name(string) | ||
| 71 | string.gsub(/\s/, '').underscore.to_sym | ||
| 72 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/find_arguments_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/find_arguments_steps.rb new file mode 100644 index 0000000..65f889c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/find_arguments_steps.rb | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | When "I include comments" do | ||
| 2 | @results = nil | ||
| 3 | @options[:include] = :comments | ||
| 4 | end | ||
| 5 | |||
| 6 | When /^I get the first comment$/ do | ||
| 7 | @comment = Comment.find(:first) | ||
| 8 | end | ||
| 9 | |||
| 10 | When /^I track queries$/ do | ||
| 11 | $queries_executed = [] | ||
| 12 | end | ||
| 13 | |||
| 14 | When /^I compare comments$/ do | ||
| 15 | results.first.comments.first.should == @comment | ||
| 16 | end | ||
| 17 | |||
| 18 | When /^I select only content$/ do | ||
| 19 | @results = nil | ||
| 20 | @options[:select] = "id, content" | ||
| 21 | end | ||
| 22 | |||
| 23 | Then /^I should have (\d+) quer[yies]+$/ do |count| | ||
| 24 | $queries_executed.length.should == count.to_i | ||
| 25 | end | ||
| 26 | |||
| 27 | Then /^I should not get an error accessing the subject$/ do | ||
| 28 | lambda { results.first.subject }.should_not raise_error | ||
| 29 | end | ||
| 30 | |||
| 31 | Then /^I should get an error accessing the subject$/ do | ||
| 32 | error_class = NoMethodError | ||
| 33 | error_class = ActiveRecord::MissingAttributeError if ActiveRecord.constants.include?("MissingAttributeError") | ||
| 34 | |||
| 35 | lambda { results.first.subject }.should raise_error(error_class) | ||
| 36 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/gamma_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/gamma_steps.rb new file mode 100644 index 0000000..c4fbe20 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/gamma_steps.rb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | When /^I destroy gamma (\w+) without callbacks$/ do |name| | ||
| 2 | @results = nil | ||
| 3 | gamma = Gamma.find_by_name(name) | ||
| 4 | Gamma.delete(gamma.id) if gamma | ||
| 5 | end | ||
| 6 | |||
| 7 | Then "I should get a single result of nil" do | ||
| 8 | results.should == [nil] | ||
| 9 | end | ||
| 10 | |||
| 11 | Then /^I should get a single gamma result with a name of (\w+)$/ do |name| | ||
| 12 | results.length.should == 1 | ||
| 13 | results.first.should be_kind_of(Gamma) | ||
| 14 | results.first.name.should == name | ||
| 15 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/search_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/search_steps.rb new file mode 100644 index 0000000..8c64dd7 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/search_steps.rb | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | When /^I search for the specific id of (\d+) in the (\w+) index$/ do |id, index| | ||
| 2 | @id = id.to_i | ||
| 3 | @index = index | ||
| 4 | end | ||
| 5 | |||
| 6 | When /^I search for the document id of (\w+) (\w+) in the (\w+) index$/ do |model, name, index| | ||
| 7 | model = model.gsub(/\s/, '_').camelize.constantize | ||
| 8 | @id = model.find_by_name(name).sphinx_document_id | ||
| 9 | @index = index | ||
| 10 | end | ||
| 11 | |||
| 12 | Then "it should exist" do | ||
| 13 | ThinkingSphinx::Search.search_for_id(@id, @index).should == true | ||
| 14 | end | ||
| 15 | |||
| 16 | Then "it should not exist" do | ||
| 17 | ThinkingSphinx::Search.search_for_id(@id, @index).should == false | ||
| 18 | end | ||
| 19 | |||
| 20 | Then "it should exist if using Rails 2.1 or newer" do | ||
| 21 | require 'active_record/version' | ||
| 22 | unless ActiveRecord::VERSION::STRING.to_f < 2.1 | ||
| 23 | ThinkingSphinx::Search.search_for_id(@id, @index).should == true | ||
| 24 | end | ||
| 25 | end | ||
| 26 | |||
| 27 | Then "it should not exist if using Rails 2.1 or newer" do | ||
| 28 | require 'active_record/version' | ||
| 29 | unless ActiveRecord::VERSION::STRING.to_f < 2.1 | ||
| 30 | ThinkingSphinx::Search.search_for_id(@id, @index).should == false | ||
| 31 | end | ||
| 32 | end | ||
| 33 | |||
| 34 | Then /^I can iterate by result and group and count$/ do | ||
| 35 | results.each_with_groupby_and_count do |result, group, count| | ||
| 36 | result.should be_kind_of(@model) | ||
| 37 | count.should be_kind_of(Integer) | ||
| 38 | group.should be_kind_of(Integer) | ||
| 39 | end | ||
| 40 | end | ||
| 41 | |||
| 42 | Then "each result id should match the corresponding sphinx internal id" do | ||
| 43 | results.each_with_sphinx_internal_id do |result, id| | ||
| 44 | result.id.should == id | ||
| 45 | end | ||
| 46 | end | ||
| 47 | |||
| 48 | Then "I should have an array of integers" do | ||
| 49 | results.each do |result| | ||
| 50 | result.should be_kind_of(Integer) | ||
| 51 | end | ||
| 52 | end | ||
| 53 | |||
| 54 | Then "searching for ids should match the record ids of the normal search results" do | ||
| 55 | normal_results = results | ||
| 56 | |||
| 57 | # reset search, switch method | ||
| 58 | @results = nil | ||
| 59 | @method = :search_for_ids | ||
| 60 | |||
| 61 | results.should == normal_results.collect(&:id) | ||
| 62 | end | ||
| 63 | |||
| 64 | Then /^I should get a value of (\d+)$/ do |count| | ||
| 65 | results.should == count.to_i | ||
| 66 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/step_definitions/sphinx_steps.rb b/vendor/plugins/thinking-sphinx/features/step_definitions/sphinx_steps.rb new file mode 100644 index 0000000..1633249 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/step_definitions/sphinx_steps.rb | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | Given "Sphinx is running" do | ||
| 2 | ThinkingSphinx::Configuration.instance.controller.should be_running | ||
| 3 | end | ||
| 4 | |||
| 5 | When "I kill the Sphinx process" do | ||
| 6 | Process.kill(9, ThinkingSphinx.sphinx_pid.to_i) | ||
| 7 | end | ||
| 8 | |||
| 9 | When "I wait for Sphinx to catch up" do | ||
| 10 | sleep(0.25) | ||
| 11 | end | ||
| 12 | |||
| 13 | When "I start Sphinx" do | ||
| 14 | ThinkingSphinx::Configuration.instance.controller.start | ||
| 15 | end | ||
| 16 | |||
| 17 | When "I stop Sphinx" do | ||
| 18 | ThinkingSphinx::Configuration.instance.controller.stop | ||
| 19 | end | ||
| 20 | |||
| 21 | Then "Sphinx should be running" do | ||
| 22 | ThinkingSphinx.sphinx_running?.should be_true | ||
| 23 | end | ||
| 24 | |||
| 25 | Then "Sphinx should not be running" do | ||
| 26 | ThinkingSphinx.sphinx_running?.should be_false | ||
| 27 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/.gitignore b/vendor/plugins/thinking-sphinx/features/support/db/.gitignore new file mode 100644 index 0000000..01bb46d --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/.gitignore | |||
| @@ -0,0 +1 @@ | |||
| database.yml \ No newline at end of file | |||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/active_record.rb b/vendor/plugins/thinking-sphinx/features/support/db/active_record.rb new file mode 100644 index 0000000..fcb622f --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/active_record.rb | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | require 'yaml' | ||
| 2 | require 'active_record' | ||
| 3 | |||
| 4 | # Database Defaults | ||
| 5 | host = "localhost" | ||
| 6 | username = "thinking_sphinx" | ||
| 7 | password = nil | ||
| 8 | |||
| 9 | # Read in YAML file | ||
| 10 | if File.exist?("features/support/db/database.yml") | ||
| 11 | config = YAML.load open("features/support/db/database.yml") | ||
| 12 | host = config["host"] || host | ||
| 13 | username = config["username"] || username | ||
| 14 | password = config["password"] || password | ||
| 15 | end | ||
| 16 | |||
| 17 | # Set up Connection | ||
| 18 | ActiveRecord::Base.establish_connection( | ||
| 19 | :adapter => Database, | ||
| 20 | :database => 'thinking_sphinx', | ||
| 21 | :username => username, | ||
| 22 | :password => password, | ||
| 23 | :host => host | ||
| 24 | ) | ||
| 25 | |||
| 26 | # Copied from ActiveRecord's test suite | ||
| 27 | ActiveRecord::Base.connection.class.class_eval do | ||
| 28 | IGNORED_SQL = [ | ||
| 29 | /^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, | ||
| 30 | /^SELECT @@ROWCOUNT/, /^SHOW FIELDS/ | ||
| 31 | ] | ||
| 32 | |||
| 33 | def execute_with_query_record(sql, name = nil, &block) | ||
| 34 | $queries_executed ||= [] | ||
| 35 | $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r } | ||
| 36 | execute_without_query_record(sql, name, &block) | ||
| 37 | end | ||
| 38 | |||
| 39 | alias_method_chain :execute, :query_record | ||
| 40 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/database.example.yml b/vendor/plugins/thinking-sphinx/features/support/db/database.example.yml new file mode 100644 index 0000000..d7b17c1 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/database.example.yml | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | username: root | ||
| 2 | host: localhost | ||
| 3 | password: \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_alphas.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_alphas.rb new file mode 100644 index 0000000..c9efab9 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_alphas.rb | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :alphas, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | t.column :value, :integer, :null => false | ||
| 4 | t.column :cost, :decimal, :precision => 10, :scale => 6 | ||
| 5 | t.column :created_on, :date | ||
| 6 | t.column :created_at, :timestamp | ||
| 7 | end | ||
| 8 | |||
| 9 | Alpha.create :name => "one", :value => 1, :cost => 1.51, :created_on => 1.day.ago.to_date, :created_at => 1.day.ago | ||
| 10 | Alpha.create :name => "two", :value => 2, :cost => 2.52, :created_on => 2.day.ago.to_date, :created_at => 2.day.ago | ||
| 11 | Alpha.create :name => "three", :value => 3, :cost => 3.53, :created_on => 3.day.ago.to_date, :created_at => 3.day.ago | ||
| 12 | Alpha.create :name => "four", :value => 4, :cost => 4.54, :created_on => 4.day.ago.to_date, :created_at => 4.day.ago | ||
| 13 | Alpha.create :name => "five", :value => 5, :cost => 5.55, :created_on => 5.day.ago.to_date, :created_at => 5.day.ago | ||
| 14 | Alpha.create :name => "six", :value => 6, :cost => 6.56, :created_on => 6.day.ago.to_date, :created_at => 6.day.ago | ||
| 15 | Alpha.create :name => "seven", :value => 7, :cost => 7.57, :created_on => 7.day.ago.to_date, :created_at => 7.day.ago | ||
| 16 | Alpha.create :name => "eight", :value => 8, :cost => 8.58, :created_on => 8.day.ago.to_date, :created_at => 8.day.ago | ||
| 17 | Alpha.create :name => "nine", :value => 9, :cost => 9.59, :created_on => 9.day.ago.to_date, :created_at => 9.day.ago | ||
| 18 | Alpha.create :name => "ten", :value => 10, :cost => 10.50, :created_on => 10.day.ago.to_date, :created_at => 10.day.ago | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_animals.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_animals.rb new file mode 100644 index 0000000..7619776 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_animals.rb | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :animals, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | t.column :type, :string | ||
| 4 | t.column :delta, :boolean, :null => false, :default => false | ||
| 5 | end | ||
| 6 | |||
| 7 | %w( rogue nat molly jasper moggy ).each do |name| | ||
| 8 | Cat.create :name => name | ||
| 9 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_betas.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_betas.rb new file mode 100644 index 0000000..1d6cde5 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_betas.rb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :betas, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | t.column :delta, :boolean, :null => false, :default => false | ||
| 4 | end | ||
| 5 | |||
| 6 | Beta.create :name => "one" | ||
| 7 | Beta.create :name => "two" | ||
| 8 | Beta.create :name => "three" | ||
| 9 | Beta.create :name => "four" | ||
| 10 | Beta.create :name => "five" | ||
| 11 | Beta.create :name => "six" | ||
| 12 | Beta.create :name => "seven" | ||
| 13 | Beta.create :name => "eight" | ||
| 14 | Beta.create :name => "nine" | ||
| 15 | Beta.create :name => "ten" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_boxes.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_boxes.rb new file mode 100644 index 0000000..380c809 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_boxes.rb | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :boxes, :force => true do |t| | ||
| 2 | t.column :width, :integer, :null => false | ||
| 3 | t.column :length, :integer, :null => false | ||
| 4 | t.column :depth, :integer, :null => false | ||
| 5 | end | ||
| 6 | |||
| 7 | (1..10).each do |i| | ||
| 8 | Box.create :width => i, :length => i, :depth => i | ||
| 9 | end | ||
| 10 | |||
| 11 | (11..20).each do |i| | ||
| 12 | Box.create :width => i, :length => i+1, :depth => i+2 | ||
| 13 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_categories.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_categories.rb new file mode 100644 index 0000000..3c7da6a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_categories.rb | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :categories, :force => true do |t| | ||
| 2 | t.column :name, :string | ||
| 3 | end | ||
| 4 | |||
| 5 | Category.create :name => "hello" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_comments.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_comments.rb new file mode 100644 index 0000000..da4531a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_comments.rb | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :comments, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | t.column :email, :string | ||
| 4 | t.column :url, :string | ||
| 5 | t.column :content, :text | ||
| 6 | t.column :post_id, :integer, :null => false | ||
| 7 | t.column :category_id, :integer, :null => false | ||
| 8 | end | ||
| 9 | |||
| 10 | Comment.create( | ||
| 11 | :name => "Pat", | ||
| 12 | :content => "+1", | ||
| 13 | :post_id => 1, | ||
| 14 | :category_id => 1 | ||
| 15 | ) | ||
| 16 | |||
| 17 | Comment.create( | ||
| 18 | :name => "Menno", | ||
| 19 | :content => "Second post!", | ||
| 20 | :post_id => 1, | ||
| 21 | :category_id => 1 | ||
| 22 | ) | ||
| 23 | |||
| 24 | Comment.create :name => 'A', :post_id => 1, :content => 'Es un hecho establecido hace demasiado tiempo que un lector se distraerá con el contenido del texto', :category_id => 1 | ||
| 25 | Comment.create :name => 'B', :post_id => 1, :content => 'de un sitio mientras que mira su diseño. El punto de usar Lorem Ipsum es que tiene una distribución', :category_id => 1 | ||
| 26 | Comment.create :name => 'C', :post_id => 1, :content => 'más o menos normal de las letras, al contrario de usar textos como por ejemplo "Contenido aquÃ', :category_id => 1 | ||
| 27 | Comment.create :name => 'D', :post_id => 1, :content => 'contenido aquÃ". Estos textos hacen parecerlo un español que se puede leer. Muchos paquetes de', :category_id => 1 | ||
| 28 | Comment.create :name => 'E', :post_id => 1, :content => 'autoedición y editores de páginas web usan el Lorem Ipsum como su texto por defecto, y al hacer una', :category_id => 1 | ||
| 29 | Comment.create :name => 'F', :post_id => 1, :content => 'búsqueda de "Lorem Ipsum" va a dar por resultado muchos sitios web que usan este texto si se', :category_id => 1 | ||
| 30 | |||
| 31 | # The one we'll really want to find via Sphinx search | ||
| 32 | Comment.create :name => 'G', :post_id => 1, :content => 'Turtle', :category_id => 1 | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_delayed_betas.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_delayed_betas.rb new file mode 100644 index 0000000..af0a374 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_delayed_betas.rb | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :delayed_betas, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | t.column :delta, :boolean, :null => false, :default => false | ||
| 4 | end | ||
| 5 | |||
| 6 | ActiveRecord::Base.connection.create_table :delayed_jobs, :force => true do |t| | ||
| 7 | t.column :priority, :integer, :default => 0 | ||
| 8 | t.column :attempts, :integer, :default => 0 | ||
| 9 | t.column :handler, :text | ||
| 10 | t.column :last_error, :string | ||
| 11 | t.column :run_at, :datetime | ||
| 12 | t.column :locked_at, :datetime | ||
| 13 | t.column :failed_at, :datetime | ||
| 14 | t.column :locked_by, :string | ||
| 15 | t.column :created_at, :datetime | ||
| 16 | t.column :updated_at, :datetime | ||
| 17 | end | ||
| 18 | |||
| 19 | DelayedBeta.create :name => "one" | ||
| 20 | DelayedBeta.create :name => "two" | ||
| 21 | DelayedBeta.create :name => "three" | ||
| 22 | DelayedBeta.create :name => "four" | ||
| 23 | DelayedBeta.create :name => "five" | ||
| 24 | DelayedBeta.create :name => "six" | ||
| 25 | DelayedBeta.create :name => "seven" | ||
| 26 | DelayedBeta.create :name => "eight" | ||
| 27 | DelayedBeta.create :name => "nine" | ||
| 28 | DelayedBeta.create :name => "ten" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_developers.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_developers.rb new file mode 100644 index 0000000..32788f0 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_developers.rb | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | require 'faker' | ||
| 2 | |||
| 3 | ActiveRecord::Base.connection.create_table :developers, :force => true do |t| | ||
| 4 | t.column :name, :string, :null => false | ||
| 5 | t.column :city, :string | ||
| 6 | t.column :state, :string | ||
| 7 | t.column :country, :string | ||
| 8 | t.column :age, :integer | ||
| 9 | end | ||
| 10 | |||
| 11 | Developer.create :name => "Pat Allan", :city => "Melbourne", :state => "Victoria", :country => "Australia", :age => 26 | ||
| 12 | |||
| 13 | 2.times do | ||
| 14 | Developer.create :name => Faker::Name.name, :city => "Melbourne", :state => "Victoria", :country => "Australia", :age => 30 | ||
| 15 | end | ||
| 16 | |||
| 17 | 2.times do | ||
| 18 | Developer.create :name => Faker::Name.name, :city => "Sydney", :state => "New South Wales", :country => "Australia", :age => 28 | ||
| 19 | end | ||
| 20 | |||
| 21 | 2.times do | ||
| 22 | Developer.create :name => Faker::Name.name, :city => "Adelaide", :state => "South Australia", :country => "Australia", :age => 32 | ||
| 23 | end | ||
| 24 | |||
| 25 | 2.times do | ||
| 26 | Developer.create :name => Faker::Name.name, :city => "Bendigo", :state => "Victoria", :country => "Australia", :age => 30 | ||
| 27 | end | ||
| 28 | |||
| 29 | 2.times do | ||
| 30 | Developer.create :name => Faker::Name.name, :city => "Goulburn", :state => "New South Wales", :country => "Australia", :age => 28 | ||
| 31 | end | ||
| 32 | |||
| 33 | 2.times do | ||
| 34 | Developer.create :name => Faker::Name.name, :city => "Auckland", :state => "North Island", :country => "New Zealand", :age => 32 | ||
| 35 | end | ||
| 36 | |||
| 37 | 2.times do | ||
| 38 | Developer.create :name => Faker::Name.name, :city => "Christchurch", :state => "South Island", :country => "New Zealand", :age => 30 | ||
| 39 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_extensible_betas.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_extensible_betas.rb new file mode 100644 index 0000000..0d1a84d --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_extensible_betas.rb | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :extensible_betas, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | t.column :delta, :boolean, :null => false, :default => false | ||
| 4 | t.column :changed_by_generic, :boolean, :null => false, :default => false | ||
| 5 | end | ||
| 6 | |||
| 7 | ExtensibleBeta.create :name => "one" | ||
| 8 | ExtensibleBeta.create :name => "two" | ||
| 9 | ExtensibleBeta.create :name => "three" | ||
| 10 | ExtensibleBeta.create :name => "four" | ||
| 11 | ExtensibleBeta.create :name => "five" | ||
| 12 | ExtensibleBeta.create :name => "six" | ||
| 13 | ExtensibleBeta.create :name => "seven" | ||
| 14 | ExtensibleBeta.create :name => "eight" | ||
| 15 | ExtensibleBeta.create :name => "nine" | ||
| 16 | ExtensibleBeta.create :name => "ten" \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_gammas.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_gammas.rb new file mode 100644 index 0000000..5c85b8d --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_gammas.rb | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :gammas, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | end | ||
| 4 | |||
| 5 | Gamma.create :name => "one" | ||
| 6 | Gamma.create :name => "two" | ||
| 7 | Gamma.create :name => "three" | ||
| 8 | Gamma.create :name => "four" | ||
| 9 | Gamma.create :name => "five" | ||
| 10 | Gamma.create :name => "six" | ||
| 11 | Gamma.create :name => "seven" | ||
| 12 | Gamma.create :name => "eight" | ||
| 13 | Gamma.create :name => "nine" | ||
| 14 | Gamma.create :name => "ten" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_people.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_people.rb new file mode 100644 index 0000000..51b4d31 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_people.rb | |||
| @@ -0,0 +1,1014 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :people, :force => true do |t| | ||
| 2 | t.column :first_name, :string | ||
| 3 | t.column :middle_initial, :string | ||
| 4 | t.column :last_name, :string | ||
| 5 | t.column :gender, :string | ||
| 6 | t.column :street_address, :string | ||
| 7 | t.column :city, :string | ||
| 8 | t.column :state, :string | ||
| 9 | t.column :postcode, :string | ||
| 10 | t.column :email, :string | ||
| 11 | t.column :birthday, :datetime | ||
| 12 | t.column :delta, :boolean, :null => false, :default => false | ||
| 13 | end | ||
| 14 | |||
| 15 | Person.create :gender => "female", :first_name => "Ellie", :middle_initial => "K", :last_name => "Ford", :street_address => "38 Mills Street", :city => "Eagle Farm Bc", :state => "QLD", :postcode => "4009", :email => "Ellie.K.Ford@mailinator.com", :birthday => "1970/1/23 00:00:00" | ||
| 16 | Person.create :gender => "female", :first_name => "Aaliyah", :middle_initial => "E", :last_name => "Allen", :street_address => "71 Murphy Street", :city => "Wyola West", :state => "WA", :postcode => "6407", :email => "Aaliyah.E.Allen@dodgit.com", :birthday => "1980/3/23 00:00:00" | ||
| 17 | Person.create :gender => "male", :first_name => "Callum", :middle_initial => "C", :last_name => "Miah", :street_address => "89 Dalgarno Street", :city => "Bullawa Creek", :state => "NSW", :postcode => "2390", :email => "Callum.C.Miah@trashymail.com", :birthday => "1973/3/25 00:00:00" | ||
| 18 | Person.create :gender => "male", :first_name => "Finley", :middle_initial => "L", :last_name => "Buckley", :street_address => "18 Queen Street", :city => "Manly Vale", :state => "NSW", :postcode => "2093", :email => "Finley.L.Buckley@spambob.com", :birthday => "1962/11/20 00:00:00" | ||
| 19 | Person.create :gender => "female", :first_name => "Poppy", :middle_initial => "A", :last_name => "Hilton", :street_address => "36 Nerrigundah Drive", :city => "Nyora", :state => "VIC", :postcode => "3987", :email => "Poppy.A.Hilton@dodgit.com", :birthday => "1972/10/30 00:00:00" | ||
| 20 | Person.create :gender => "female", :first_name => "Eloise", :middle_initial => "Z", :last_name => "Kennedy", :street_address => "18 Mt Berryman Road", :city => "Lilydale", :state => "QLD", :postcode => "4344", :email => "Eloise.Z.Kennedy@spambob.com", :birthday => "1973/9/28 00:00:00" | ||
| 21 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "L", :last_name => "Manning", :street_address => "60 Ocean Pde", :city => "Greenvale", :state => "QLD", :postcode => "4816", :email => "Shannon.L.Manning@dodgit.com", :birthday => "1956/6/13 00:00:00" | ||
| 22 | Person.create :gender => "male", :first_name => "Oscar", :middle_initial => "C", :last_name => "Lawson", :street_address => "43 Feather Street", :city => "Battery Hill", :state => "QLD", :postcode => "4551", :email => "Oscar.C.Lawson@spambob.com", :birthday => "1979/10/17 00:00:00" | ||
| 23 | Person.create :gender => "female", :first_name => "Sofia", :middle_initial => "K", :last_name => "Bray", :street_address => "26 Clifton Street", :city => "Pental Island", :state => "VIC", :postcode => "3586", :email => "Sofia.K.Bray@mailinator.com", :birthday => "1970/5/10 00:00:00" | ||
| 24 | Person.create :gender => "male", :first_name => "Andrew", :middle_initial => "N", :last_name => "Byrne", :street_address => "35 Cecil Street", :city => "Monash Park", :state => "NSW", :postcode => "2111", :email => "Andrew.N.Byrne@spambob.com", :birthday => "1983/2/16 00:00:00" | ||
| 25 | Person.create :gender => "female", :first_name => "Jasmine", :middle_initial => "D", :last_name => "Whittaker", :street_address => "91 Creegans Road", :city => "Upper Eden Creek", :state => "NSW", :postcode => "2474", :email => "Jasmine.D.Whittaker@dodgit.com", :birthday => "1954/11/25 00:00:00" | ||
| 26 | Person.create :gender => "male", :first_name => "Charlie", :middle_initial => "L", :last_name => "Savage", :street_address => "48 Cecil Street", :city => "Denistone East", :state => "NSW", :postcode => "2112", :email => "Charlie.L.Savage@mailinator.com", :birthday => "1962/6/2 00:00:00" | ||
| 27 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "M", :last_name => "Edwards", :street_address => "75 Point Walter Road", :city => "Wattleup", :state => "WA", :postcode => "6166", :email => "Ethan.M.Edwards@dodgit.com", :birthday => "1985/6/4 00:00:00" | ||
| 28 | Person.create :gender => "female", :first_name => "Imogen", :middle_initial => "L", :last_name => "Macdonald", :street_address => "2 Bass Street", :city => "Dungarubba", :state => "NSW", :postcode => "2480", :email => "Imogen.L.Macdonald@mailinator.com", :birthday => "1963/7/1 00:00:00" | ||
| 29 | Person.create :gender => "female", :first_name => "Isabel", :middle_initial => "H", :last_name => "Nolan", :street_address => "58 Saggers Road", :city => "Lake King", :state => "WA", :postcode => "6356", :email => "Isabel.H.Nolan@spambob.com", :birthday => "1951/1/4 00:00:00" | ||
| 30 | Person.create :gender => "male", :first_name => "Peter", :middle_initial => "C", :last_name => "Andrews", :street_address => "53 Wilson Street", :city => "Sea Lake", :state => "VIC", :postcode => "3533", :email => "Peter.C.Andrews@dodgit.com", :birthday => "1965/7/25 00:00:00" | ||
| 31 | Person.create :gender => "female", :first_name => "Hollie", :middle_initial => "C", :last_name => "Hunter", :street_address => "34 Cornish Street", :city => "Kensington", :state => "VIC", :postcode => "3031", :email => "Hollie.C.Hunter@mailinator.com", :birthday => "1954/2/16 00:00:00" | ||
| 32 | Person.create :gender => "male", :first_name => "Jonathan", :middle_initial => "C", :last_name => "Turner", :street_address => "2 Kopkes Road", :city => "Carngham", :state => "VIC", :postcode => "3351", :email => "Jonathan.C.Turner@trashymail.com", :birthday => "1963/8/26 00:00:00" | ||
| 33 | Person.create :gender => "female", :first_name => "Kate", :middle_initial => "S", :last_name => "Doyle", :street_address => "42 Gregory Way", :city => "Mungalup", :state => "WA", :postcode => "6225", :email => "Kate.S.Doyle@mailinator.com", :birthday => "1974/1/5 00:00:00" | ||
| 34 | Person.create :gender => "male", :first_name => "Harley", :middle_initial => "M", :last_name => "Abbott", :street_address => "39 Faulkner Street", :city => "Tilbuster", :state => "NSW", :postcode => "2350", :email => "Harley.M.Abbott@trashymail.com", :birthday => "1953/10/4 00:00:00" | ||
| 35 | Person.create :gender => "male", :first_name => "Morgan", :middle_initial => "E", :last_name => "Iqbal", :street_address => "64 Carlisle Street", :city => "Dysart", :state => "VIC", :postcode => "3660", :email => "Morgan.E.Iqbal@spambob.com", :birthday => "1954/7/6 00:00:00" | ||
| 36 | Person.create :gender => "female", :first_name => "Phoebe", :middle_initial => "T", :last_name => "Wells", :street_address => "10 Mnimbah Road", :city => "Eccleston", :state => "NSW", :postcode => "2311", :email => "Phoebe.T.Wells@trashymail.com", :birthday => "1949/5/27 00:00:00" | ||
| 37 | Person.create :gender => "male", :first_name => "Finley", :middle_initial => "I", :last_name => "Martin", :street_address => "15 Thomas Lane", :city => "Epping", :state => "VIC", :postcode => "3076", :email => "Finley.I.Martin@dodgit.com", :birthday => "1983/3/12 00:00:00" | ||
| 38 | Person.create :gender => "female", :first_name => "Eva", :middle_initial => "Z", :last_name => "Graham", :street_address => "70 Ranworth Road", :city => "Canning Vale South", :state => "WA", :postcode => "6155", :email => "Eva.Z.Graham@spambob.com", :birthday => "1963/2/16 00:00:00" | ||
| 39 | Person.create :gender => "female", :first_name => "Rachel", :middle_initial => "M", :last_name => "Ball", :street_address => "37 Bellion Drive", :city => "Carlotta", :state => "WA", :postcode => "6275", :email => "Rachel.M.Ball@mailinator.com", :birthday => "1959/5/28 00:00:00" | ||
| 40 | Person.create :gender => "female", :first_name => "Alicia", :middle_initial => "H", :last_name => "Hancock", :street_address => "32 Atkinson Way", :city => "Gnoorea", :state => "WA", :postcode => "6714", :email => "Alicia.H.Hancock@mailinator.com", :birthday => "1946/6/14 00:00:00" | ||
| 41 | Person.create :gender => "female", :first_name => "Jennifer", :middle_initial => "K", :last_name => "Farrell", :street_address => "93 Frouds Road", :city => "Johnsonville", :state => "VIC", :postcode => "3902", :email => "Jennifer.K.Farrell@mailinator.com", :birthday => "1956/9/3 00:00:00" | ||
| 42 | Person.create :gender => "female", :first_name => "Chloe", :middle_initial => "T", :last_name => "Harvey", :street_address => "77 Endeavour Drive", :city => "Duck Ponds", :state => "SA", :postcode => "5607", :email => "Chloe.T.Harvey@dodgit.com", :birthday => "1944/11/20 00:00:00" | ||
| 43 | Person.create :gender => "female", :first_name => "Hollie", :middle_initial => "T", :last_name => "Waters", :street_address => "24 Avondale Drive", :city => "Corrimal East", :state => "NSW", :postcode => "2518", :email => "Hollie.T.Waters@dodgit.com", :birthday => "1968/10/2 00:00:00" | ||
| 44 | Person.create :gender => "male", :first_name => "Ben", :middle_initial => "L", :last_name => "Steele", :street_address => "43 Cubbine Road", :city => "North Bodallin", :state => "WA", :postcode => "6424", :email => "Ben.L.Steele@dodgit.com", :birthday => "1952/10/30 00:00:00" | ||
| 45 | Person.create :gender => "female", :first_name => "Isobel", :middle_initial => "S", :last_name => "Stewart", :street_address => "59 Hummocky Road", :city => "De Mole River", :state => "SA", :postcode => "5223", :email => "Isobel.S.Stewart@spambob.com", :birthday => "1940/5/6 00:00:00" | ||
| 46 | Person.create :gender => "female", :first_name => "Hollie", :middle_initial => "K", :last_name => "Byrne", :street_address => "56 Ranworth Road", :city => "Willagee Central", :state => "WA", :postcode => "6156", :email => "Hollie.K.Byrne@pookmail.com", :birthday => "1964/10/3 00:00:00" | ||
| 47 | Person.create :gender => "female", :first_name => "Victoria", :middle_initial => "H", :last_name => "Dobson", :street_address => "6 Creedon Street", :city => "Westmeadows", :state => "VIC", :postcode => "3049", :email => "Victoria.H.Dobson@trashymail.com", :birthday => "1968/10/22 00:00:00" | ||
| 48 | Person.create :gender => "female", :first_name => "Summer", :middle_initial => "J", :last_name => "Harding", :street_address => "19 Cornish Street", :city => "Quandong", :state => "VIC", :postcode => "3030", :email => "Summer.J.Harding@mailinator.com", :birthday => "1953/11/15 00:00:00" | ||
| 49 | Person.create :gender => "female", :first_name => "Aimee", :middle_initial => "E", :last_name => "Kirk", :street_address => "43 Main Street", :city => "Qualco", :state => "SA", :postcode => "5322", :email => "Aimee.E.Kirk@pookmail.com", :birthday => "1947/7/3 00:00:00" | ||
| 50 | Person.create :gender => "female", :first_name => "Amelia", :middle_initial => "A", :last_name => "Hyde", :street_address => "31 South Molle Boulevard", :city => "Mission Beach", :state => "QLD", :postcode => "4852", :email => "Amelia.A.Hyde@mailinator.com", :birthday => "1941/7/15 00:00:00" | ||
| 51 | Person.create :gender => "male", :first_name => "Leo", :middle_initial => "K", :last_name => "Storey", :street_address => "34 McGregor Street", :city => "Trida", :state => "NSW", :postcode => "2878", :email => "Leo.K.Storey@trashymail.com", :birthday => "1960/7/10 00:00:00" | ||
| 52 | Person.create :gender => "female", :first_name => "Hannah", :middle_initial => "J", :last_name => "Young", :street_address => "39 Acheron Road", :city => "Willung South", :state => "VIC", :postcode => "3844", :email => "Hannah.J.Young@spambob.com", :birthday => "1965/8/3 00:00:00" | ||
| 53 | Person.create :gender => "female", :first_name => "Chelsea", :middle_initial => "H", :last_name => "Nelson", :street_address => "17 Crofts Road", :city => "Tamboon", :state => "VIC", :postcode => "3890", :email => "Chelsea.H.Nelson@dodgit.com", :birthday => "1969/9/26 00:00:00" | ||
| 54 | Person.create :gender => "male", :first_name => "Isaac", :middle_initial => "A", :last_name => "West", :street_address => "57 Webb Road", :city => "Fern Bay", :state => "NSW", :postcode => "2295", :email => "Isaac.A.West@spambob.com", :birthday => "1981/8/20 00:00:00" | ||
| 55 | Person.create :gender => "male", :first_name => "Charlie", :middle_initial => "G", :last_name => "Hancock", :street_address => "17 Burnley Street", :city => "Kyeema", :state => "SA", :postcode => "5172", :email => "Charlie.G.Hancock@trashymail.com", :birthday => "1965/12/21 00:00:00" | ||
| 56 | Person.create :gender => "male", :first_name => "Oliver", :middle_initial => "M", :last_name => "Potter", :street_address => "63 Adavale Road", :city => "Tarago", :state => "NSW", :postcode => "2580", :email => "Oliver.M.Potter@pookmail.com", :birthday => "1977/6/7 00:00:00" | ||
| 57 | Person.create :gender => "female", :first_name => "Harriet", :middle_initial => "J", :last_name => "Cameron", :street_address => "72 Manchester Road", :city => "Bundook", :state => "NSW", :postcode => "2422", :email => "Harriet.J.Cameron@dodgit.com", :birthday => "1942/2/23 00:00:00" | ||
| 58 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "E", :last_name => "Tomlinson", :street_address => "68 Roseda-Tinamba Road", :city => "Hazel Park", :state => "VIC", :postcode => "3966", :email => "Owen.E.Tomlinson@mailinator.com", :birthday => "1949/5/2 00:00:00" | ||
| 59 | Person.create :gender => "female", :first_name => "Zoe", :middle_initial => "J", :last_name => "Flynn", :street_address => "67 Fairview Street", :city => "Curdies River", :state => "VIC", :postcode => "3268", :email => "Zoe.J.Flynn@spambob.com", :birthday => "1969/2/2 00:00:00" | ||
| 60 | Person.create :gender => "female", :first_name => "Niamh", :middle_initial => "J", :last_name => "Marsh", :street_address => "35 McLaughlin Road", :city => "Taromeo", :state => "QLD", :postcode => "4306", :email => "Niamh.J.Marsh@trashymail.com", :birthday => "1970/4/30 00:00:00" | ||
| 61 | Person.create :gender => "female", :first_name => "Charlotte", :middle_initial => "Z", :last_name => "Wilson", :street_address => "76 Glenpark Road", :city => "Ulmarra", :state => "NSW", :postcode => "2462", :email => "Charlotte.Z.Wilson@dodgit.com", :birthday => "1944/1/9 00:00:00" | ||
| 62 | Person.create :gender => "male", :first_name => "Ben", :middle_initial => "J", :last_name => "Miah", :street_address => "25 Bayfield Street", :city => "Kellevie", :state => "TAS", :postcode => "7176", :email => "Ben.J.Miah@pookmail.com", :birthday => "1960/5/1 00:00:00" | ||
| 63 | Person.create :gender => "female", :first_name => "Lara", :middle_initial => "D", :last_name => "Rice", :street_address => "19 Bayfield Street", :city => "Rheban", :state => "TAS", :postcode => "7190", :email => "Lara.D.Rice@trashymail.com", :birthday => "1942/5/14 00:00:00" | ||
| 64 | Person.create :gender => "male", :first_name => "Jordan", :middle_initial => "M", :last_name => "Short", :street_address => "67 Feather Street", :city => "Mount Nebo", :state => "QLD", :postcode => "4520", :email => "Jordan.M.Short@pookmail.com", :birthday => "1977/8/17 00:00:00" | ||
| 65 | Person.create :gender => "female", :first_name => "Gracie", :middle_initial => "K", :last_name => "Davey", :street_address => "38 Marx Hill Road", :city => "Upper Thora", :state => "NSW", :postcode => "2454", :email => "Gracie.K.Davey@pookmail.com", :birthday => "1950/11/27 00:00:00" | ||
| 66 | Person.create :gender => "male", :first_name => "Harrison", :middle_initial => "D", :last_name => "Allen", :street_address => "68 Brown Street", :city => "Pymble", :state => "NSW", :postcode => "2073", :email => "Harrison.D.Allen@dodgit.com", :birthday => "1976/6/14 00:00:00" | ||
| 67 | Person.create :gender => "male", :first_name => "Ben", :middle_initial => "M", :last_name => "Charlton", :street_address => "30 Hummocky Road", :city => "Wisanger", :state => "SA", :postcode => "5223", :email => "Ben.M.Charlton@spambob.com", :birthday => "1955/4/30 00:00:00" | ||
| 68 | Person.create :gender => "female", :first_name => "Kayleigh", :middle_initial => "Z", :last_name => "Winter", :street_address => "55 Magnolia Drive", :city => "South Hurstville", :state => "NSW", :postcode => "2221", :email => "Kayleigh.Z.Winter@pookmail.com", :birthday => "1971/6/27 00:00:00" | ||
| 69 | Person.create :gender => "female", :first_name => "Rosie", :middle_initial => "J", :last_name => "Carey", :street_address => "13 Ugoa Street", :city => "Crowdy Head", :state => "NSW", :postcode => "2427", :email => "Rosie.J.Carey@spambob.com", :birthday => "1946/8/27 00:00:00" | ||
| 70 | Person.create :gender => "male", :first_name => "Spencer", :middle_initial => "S", :last_name => "Jackson", :street_address => "17 Bapaume Road", :city => "Narko", :state => "QLD", :postcode => "4352", :email => "Spencer.S.Jackson@mailinator.com", :birthday => "1946/4/11 00:00:00" | ||
| 71 | Person.create :gender => "male", :first_name => "Kyle", :middle_initial => "E", :last_name => "Bond", :street_address => "6 Village Drive", :city => "Lansvale", :state => "NSW", :postcode => "2166", :email => "Kyle.E.Bond@trashymail.com", :birthday => "1953/5/15 00:00:00" | ||
| 72 | Person.create :gender => "male", :first_name => "Toby", :middle_initial => "C", :last_name => "Burgess", :street_address => "94 Redesdale Rd", :city => "Myola", :state => "VIC", :postcode => "3551", :email => "Toby.C.Burgess@trashymail.com", :birthday => "1979/2/3 00:00:00" | ||
| 73 | Person.create :gender => "female", :first_name => "Megan", :middle_initial => "F", :last_name => "Heath", :street_address => "96 Dossiter Street", :city => "Antill Ponds", :state => "TAS", :postcode => "7120", :email => "Megan.F.Heath@trashymail.com", :birthday => "1942/6/13 00:00:00" | ||
| 74 | Person.create :gender => "male", :first_name => "Billy", :middle_initial => "M", :last_name => "Bishop", :street_address => "21 Mills Street", :city => "Nundah", :state => "QLD", :postcode => "4012", :email => "Billy.M.Bishop@dodgit.com", :birthday => "1968/11/15 00:00:00" | ||
| 75 | Person.create :gender => "male", :first_name => "Reece", :middle_initial => "G", :last_name => "Pearce", :street_address => "76 Treasure Island Avenue", :city => "Tallebudgera Valley", :state => "QLD", :postcode => "4228", :email => "Reece.G.Pearce@dodgit.com", :birthday => "1940/6/26 00:00:00" | ||
| 76 | Person.create :gender => "female", :first_name => "Skye", :middle_initial => "F", :last_name => "Bailey", :street_address => "66 Goebels Road", :city => "Hatton Vale", :state => "QLD", :postcode => "4341", :email => "Skye.F.Bailey@dodgit.com", :birthday => "1956/5/23 00:00:00" | ||
| 77 | Person.create :gender => "female", :first_name => "Emma", :middle_initial => "F", :last_name => "Parkinson", :street_address => "27 Arthur Street", :city => "Bogan", :state => "NSW", :postcode => "2825", :email => "Emma.F.Parkinson@mailinator.com", :birthday => "1948/12/11 00:00:00" | ||
| 78 | Person.create :gender => "male", :first_name => "Evan", :middle_initial => "M", :last_name => "Chambers", :street_address => "28 Pelican Road", :city => "Bathurst Street Po", :state => "TAS", :postcode => "7000", :email => "Evan.M.Chambers@dodgit.com", :birthday => "1956/7/30 00:00:00" | ||
| 79 | Person.create :gender => "male", :first_name => "Scott", :middle_initial => "S", :last_name => "Rees", :street_address => "76 Foreshore Road", :city => "Nollamara", :state => "WA", :postcode => "6061", :email => "Scott.S.Rees@mailinator.com", :birthday => "1965/4/13 00:00:00" | ||
| 80 | Person.create :gender => "female", :first_name => "Keira", :middle_initial => "M", :last_name => "Hurst", :street_address => "82 Commercial Street", :city => "Hesket", :state => "VIC", :postcode => "3442", :email => "Keira.M.Hurst@trashymail.com", :birthday => "1958/11/6 00:00:00" | ||
| 81 | Person.create :gender => "male", :first_name => "Finlay", :middle_initial => "L", :last_name => "Parkinson", :street_address => "25 Black Range Road", :city => "Quaama", :state => "NSW", :postcode => "2550", :email => "Finlay.L.Parkinson@dodgit.com", :birthday => "1952/10/18 00:00:00" | ||
| 82 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "I", :last_name => "Hartley", :street_address => "8 South Molle Boulevard", :city => "Tam O'hanter", :state => "QLD", :postcode => "4852", :email => "Owen.I.Hartley@mailinator.com", :birthday => "1974/11/9 00:00:00" | ||
| 83 | Person.create :gender => "female", :first_name => "Erin", :middle_initial => "J", :last_name => "Daly", :street_address => "88 Magnolia Drive", :city => "Beverley Park", :state => "NSW", :postcode => "2217", :email => "Erin.J.Daly@dodgit.com", :birthday => "1975/4/12 00:00:00" | ||
| 84 | Person.create :gender => "female", :first_name => "Tilly", :middle_initial => "P", :last_name => "North", :street_address => "26 Glenpark Road", :city => "Urunga", :state => "NSW", :postcode => "2455", :email => "Tilly.P.North@spambob.com", :birthday => "1968/5/4 00:00:00" | ||
| 85 | Person.create :gender => "male", :first_name => "Morgan", :middle_initial => "Z", :last_name => "Owens", :street_address => "89 Walter Crescent", :city => "Brogers Creek", :state => "NSW", :postcode => "2535", :email => "Morgan.Z.Owens@spambob.com", :birthday => "1956/10/17 00:00:00" | ||
| 86 | Person.create :gender => "female", :first_name => "Poppy", :middle_initial => "E", :last_name => "Kemp", :street_address => "63 Elizabeth Street", :city => "Munna Creek", :state => "QLD", :postcode => "4570", :email => "Poppy.E.Kemp@pookmail.com", :birthday => "1942/9/2 00:00:00" | ||
| 87 | Person.create :gender => "female", :first_name => "Katie", :middle_initial => "S", :last_name => "Davies", :street_address => "89 Mnimbah Road", :city => "Glen William", :state => "NSW", :postcode => "2321", :email => "Katie.S.Davies@pookmail.com", :birthday => "1947/6/22 00:00:00" | ||
| 88 | Person.create :gender => "female", :first_name => "Sophia", :middle_initial => "J", :last_name => "Finch", :street_address => "18 Bellion Drive", :city => "Cundinup", :state => "WA", :postcode => "6275", :email => "Sophia.J.Finch@pookmail.com", :birthday => "1940/2/3 00:00:00" | ||
| 89 | Person.create :gender => "female", :first_name => "Madison", :middle_initial => "L", :last_name => "Wells", :street_address => "28 Austin Road", :city => "Dunmarra", :state => "NT", :postcode => "0852", :email => "Madison.L.Wells@dodgit.com", :birthday => "1954/10/20 00:00:00" | ||
| 90 | Person.create :gender => "female", :first_name => "Jasmine", :middle_initial => "L", :last_name => "Blackburn", :street_address => "27 Southwell Crescent", :city => "Argyle", :state => "WA", :postcode => "6239", :email => "Jasmine.L.Blackburn@pookmail.com", :birthday => "1956/8/1 00:00:00" | ||
| 91 | Person.create :gender => "female", :first_name => "Zoe", :middle_initial => "H", :last_name => "Slater", :street_address => "42 Panorama Road", :city => "North Tamworth", :state => "NSW", :postcode => "2340", :email => "Zoe.H.Slater@dodgit.com", :birthday => "1968/11/5 00:00:00" | ||
| 92 | Person.create :gender => "male", :first_name => "Michael", :middle_initial => "N", :last_name => "Bibi", :street_address => "91 Moores Drive", :city => "Nedlands Dc", :state => "WA", :postcode => "6009", :email => "Michael.N.Bibi@trashymail.com", :birthday => "1957/10/18 00:00:00" | ||
| 93 | Person.create :gender => "male", :first_name => "Mason", :middle_initial => "A", :last_name => "Coles", :street_address => "55 Sunnyside Road", :city => "Wappilka", :state => "SA", :postcode => "5332", :email => "Mason.A.Coles@spambob.com", :birthday => "1940/8/9 00:00:00" | ||
| 94 | Person.create :gender => "male", :first_name => "Joe", :middle_initial => "R", :last_name => "Hardy", :street_address => "38 Marloo Street", :city => "Royston Park", :state => "SA", :postcode => "5070", :email => "Joe.R.Hardy@dodgit.com", :birthday => "1942/5/9 00:00:00" | ||
| 95 | Person.create :gender => "male", :first_name => "Jamie", :middle_initial => "J", :last_name => "Akhtar", :street_address => "52 Flinstone Drive", :city => "Bagdad", :state => "TAS", :postcode => "7030", :email => "Jamie.J.Akhtar@trashymail.com", :birthday => "1947/10/24 00:00:00" | ||
| 96 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "E", :last_name => "Smart", :street_address => "32 Kintyre Street", :city => "Wakerley", :state => "QLD", :postcode => "4154", :email => "Ava.E.Smart@pookmail.com", :birthday => "1975/9/6 00:00:00" | ||
| 97 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "C", :last_name => "Bond", :street_address => "60 Treasure Island Avenue", :city => "Ferny Glen", :state => "QLD", :postcode => "4275", :email => "Ethan.C.Bond@trashymail.com", :birthday => "1954/3/1 00:00:00" | ||
| 98 | Person.create :gender => "male", :first_name => "Elliot", :middle_initial => "M", :last_name => "Perry", :street_address => "52 Grayson Street", :city => "Wagga Wagga Raaf", :state => "NSW", :postcode => "2651", :email => "Elliot.M.Perry@mailinator.com", :birthday => "1960/11/9 00:00:00" | ||
| 99 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "C", :last_name => "Owen", :street_address => "69 West Street", :city => "Phillip Dc", :state => "ACT", :postcode => "2606", :email => "Louie.C.Owen@dodgit.com", :birthday => "1959/12/27 00:00:00" | ||
| 100 | Person.create :gender => "female", :first_name => "Mollie", :middle_initial => "J", :last_name => "McDonald", :street_address => "28 Inglewood Court", :city => "Fern Hill", :state => "VIC", :postcode => "3458", :email => "Mollie.J.McDonald@pookmail.com", :birthday => "1954/11/30 00:00:00" | ||
| 101 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "J", :last_name => "Perkins", :street_address => "97 Duff Street", :city => "Wyalkatchem", :state => "WA", :postcode => "6485", :email => "Maddison.J.Perkins@dodgit.com", :birthday => "1971/7/10 00:00:00" | ||
| 102 | Person.create :gender => "male", :first_name => "Ryan", :middle_initial => "J", :last_name => "Carpenter", :street_address => "79 McGregor Street", :city => "Theodore", :state => "ACT", :postcode => "2905", :email => "Ryan.J.Carpenter@spambob.com", :birthday => "1985/4/16 00:00:00" | ||
| 103 | Person.create :gender => "male", :first_name => "Bradley", :middle_initial => "M", :last_name => "Connolly", :street_address => "56 Cherry Grove", :city => "Nelson Bay", :state => "TAS", :postcode => "7330", :email => "Bradley.M.Connolly@mailinator.com", :birthday => "1983/3/13 00:00:00" | ||
| 104 | Person.create :gender => "female", :first_name => "Louise", :middle_initial => "C", :last_name => "Lee", :street_address => "63 Flinstone Drive", :city => "Bridgewater", :state => "TAS", :postcode => "7030", :email => "Louise.C.Lee@mailinator.com", :birthday => "1967/12/13 00:00:00" | ||
| 105 | Person.create :gender => "male", :first_name => "Riley", :middle_initial => "S", :last_name => "Skinner", :street_address => "93 Ranworth Road", :city => "Mount Pleasant", :state => "WA", :postcode => "6153", :email => "Riley.S.Skinner@mailinator.com", :birthday => "1980/6/16 00:00:00" | ||
| 106 | Person.create :gender => "female", :first_name => "Lara", :middle_initial => "N", :last_name => "George", :street_address => "54 McGregor Street", :city => "Wanniassa", :state => "ACT", :postcode => "2903", :email => "Lara.N.George@pookmail.com", :birthday => "1949/8/13 00:00:00" | ||
| 107 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "H", :last_name => "Wall", :street_address => "96 Quoin Road", :city => "Loira", :state => "TAS", :postcode => "7275", :email => "Isabelle.H.Wall@pookmail.com", :birthday => "1970/1/19 00:00:00" | ||
| 108 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "O", :last_name => "Francis", :street_address => "12 Oak Street", :city => "Acacia Plateau", :state => "NSW", :postcode => "2476", :email => "Tegan.O.Francis@spambob.com", :birthday => "1941/4/3 00:00:00" | ||
| 109 | Person.create :gender => "male", :first_name => "Bradley", :middle_initial => "A", :last_name => "Watson", :street_address => "11 Church Street", :city => "Coonawarra", :state => "SA", :postcode => "5263", :email => "Bradley.A.Watson@trashymail.com", :birthday => "1977/12/11 00:00:00" | ||
| 110 | Person.create :gender => "male", :first_name => "Alexander", :middle_initial => "E", :last_name => "Webster", :street_address => "83 Carolina Park Road", :city => "Hardys Bay", :state => "NSW", :postcode => "2257", :email => "Alexander.E.Webster@dodgit.com", :birthday => "1967/3/1 00:00:00" | ||
| 111 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "T", :last_name => "Fowler", :street_address => "37 Marloo Street", :city => "Hackney", :state => "SA", :postcode => "5069", :email => "Tegan.T.Fowler@pookmail.com", :birthday => "1979/3/3 00:00:00" | ||
| 112 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "K", :last_name => "Bibi", :street_address => "24 Purcell Place", :city => "Chaelundi", :state => "NSW", :postcode => "2460", :email => "Christopher.K.Bibi@dodgit.com", :birthday => "1949/9/11 00:00:00" | ||
| 113 | Person.create :gender => "male", :first_name => "Andrew", :middle_initial => "A", :last_name => "Gough", :street_address => "28 Cassinia Street", :city => "Black Creek", :state => "NSW", :postcode => "2729", :email => "Andrew.A.Gough@mailinator.com", :birthday => "1947/11/13 00:00:00" | ||
| 114 | Person.create :gender => "female", :first_name => "Naomi", :middle_initial => "J", :last_name => "Fitzgerald", :street_address => "23 Peninsula Drive", :city => "Gymea Bay", :state => "NSW", :postcode => "2227", :email => "Naomi.J.Fitzgerald@dodgit.com", :birthday => "1968/8/20 00:00:00" | ||
| 115 | Person.create :gender => "female", :first_name => "Alicia", :middle_initial => "S", :last_name => "Berry", :street_address => "5 Lewin Street", :city => "Mirrool", :state => "NSW", :postcode => "2665", :email => "Alicia.S.Berry@dodgit.com", :birthday => "1946/3/23 00:00:00" | ||
| 116 | Person.create :gender => "male", :first_name => "Harvey", :middle_initial => "C", :last_name => "Stanley", :street_address => "81 Bayview Close", :city => "Tarramba", :state => "QLD", :postcode => "4715", :email => "Harvey.C.Stanley@dodgit.com", :birthday => "1980/9/28 00:00:00" | ||
| 117 | Person.create :gender => "female", :first_name => "Lucy", :middle_initial => "J", :last_name => "Daniels", :street_address => "82 West Street", :city => "Isaacs", :state => "ACT", :postcode => "2607", :email => "Lucy.J.Daniels@spambob.com", :birthday => "1968/8/9 00:00:00" | ||
| 118 | Person.create :gender => "female", :first_name => "Cerys", :middle_initial => "J", :last_name => "Tyler", :street_address => "75 Derry Street", :city => "Petrie", :state => "QLD", :postcode => "4502", :email => "Cerys.J.Tyler@mailinator.com", :birthday => "1941/12/21 00:00:00" | ||
| 119 | Person.create :gender => "male", :first_name => "Reece", :middle_initial => "Y", :last_name => "Bell", :street_address => "98 Grandis Road", :city => "Lower Creek", :state => "NSW", :postcode => "2440", :email => "Reece.Y.Bell@spambob.com", :birthday => "1973/11/28 00:00:00" | ||
| 120 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "C", :last_name => "Hill", :street_address => "79 Walpole Avenue", :city => "Nirranda", :state => "VIC", :postcode => "3268", :email => "Shannon.C.Hill@spambob.com", :birthday => "1955/4/5 00:00:00" | ||
| 121 | Person.create :gender => "female", :first_name => "Maisie", :middle_initial => "S", :last_name => "Lee", :street_address => "43 Learmouth Street", :city => "Heathmere", :state => "VIC", :postcode => "3305", :email => "Maisie.S.Lee@spambob.com", :birthday => "1969/6/19 00:00:00" | ||
| 122 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "H", :last_name => "Connor", :street_address => "85 Sullivan Court", :city => "Whirily", :state => "VIC", :postcode => "3483", :email => "Tegan.H.Connor@trashymail.com", :birthday => "1942/12/28 00:00:00" | ||
| 123 | Person.create :gender => "female", :first_name => "Cerys", :middle_initial => "A", :last_name => "Gardner", :street_address => "96 Kaesler Road", :city => "Parilla", :state => "SA", :postcode => "5303", :email => "Cerys.A.Gardner@pookmail.com", :birthday => "1950/1/20 00:00:00" | ||
| 124 | Person.create :gender => "female", :first_name => "Hollie", :middle_initial => "L", :last_name => "Robinson", :street_address => "72 Burnley Street", :city => "Morphett Vale", :state => "SA", :postcode => "5162", :email => "Hollie.L.Robinson@dodgit.com", :birthday => "1960/5/29 00:00:00" | ||
| 125 | Person.create :gender => "male", :first_name => "Robert", :middle_initial => "C", :last_name => "Sanders", :street_address => "81 Hay Point Road", :city => "West Mackay", :state => "QLD", :postcode => "4740", :email => "Robert.C.Sanders@trashymail.com", :birthday => "1957/2/22 00:00:00" | ||
| 126 | Person.create :gender => "female", :first_name => "Jodie", :middle_initial => "M", :last_name => "Leach", :street_address => "75 Thomas Lane", :city => "Lalor Plaza", :state => "VIC", :postcode => "3075", :email => "Jodie.M.Leach@dodgit.com", :birthday => "1979/3/7 00:00:00" | ||
| 127 | Person.create :gender => "male", :first_name => "Luca", :middle_initial => "K", :last_name => "Barnes", :street_address => "91 Zipfs Road", :city => "Goodna Dc", :state => "QLD", :postcode => "4300", :email => "Luca.K.Barnes@mailinator.com", :birthday => "1981/8/12 00:00:00" | ||
| 128 | Person.create :gender => "male", :first_name => "Andrew", :middle_initial => "E", :last_name => "Dyer", :street_address => "9 Cornish Street", :city => "Deer Park", :state => "VIC", :postcode => "3023", :email => "Andrew.E.Dyer@trashymail.com", :birthday => "1963/10/1 00:00:00" | ||
| 129 | Person.create :gender => "male", :first_name => "Ben", :middle_initial => "M", :last_name => "Steele", :street_address => "22 Quintin Street", :city => "Caboolture South", :state => "QLD", :postcode => "4510", :email => "Ben.M.Steele@spambob.com", :birthday => "1973/9/25 00:00:00" | ||
| 130 | Person.create :gender => "male", :first_name => "Rhys", :middle_initial => "O", :last_name => "Morgan", :street_address => "68 Reynolds Road", :city => "Glenwood", :state => "QLD", :postcode => "4570", :email => "Rhys.O.Morgan@spambob.com", :birthday => "1945/5/25 00:00:00" | ||
| 131 | Person.create :gender => "female", :first_name => "Niamh", :middle_initial => "J", :last_name => "Ross", :street_address => "92 Panorama Road", :city => "Piallamore", :state => "NSW", :postcode => "2340", :email => "Niamh.J.Ross@mailinator.com", :birthday => "1961/9/22 00:00:00" | ||
| 132 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "A", :last_name => "Bolton", :street_address => "95 Treasure Island Avenue", :city => "Biddaddaba", :state => "QLD", :postcode => "4275", :email => "Tom.A.Bolton@spambob.com", :birthday => "1977/8/4 00:00:00" | ||
| 133 | Person.create :gender => "male", :first_name => "Alfie", :middle_initial => "L", :last_name => "Gray", :street_address => "96 Meyer Road", :city => "Nuriootpa", :state => "SA", :postcode => "5355", :email => "Alfie.L.Gray@mailinator.com", :birthday => "1941/5/19 00:00:00" | ||
| 134 | Person.create :gender => "female", :first_name => "Imogen", :middle_initial => "K", :last_name => "Hayes", :street_address => "92 Marley Point Road", :city => "Buchan South", :state => "VIC", :postcode => "3885", :email => "Imogen.K.Hayes@spambob.com", :birthday => "1979/11/13 00:00:00" | ||
| 135 | Person.create :gender => "male", :first_name => "Daniel", :middle_initial => "N", :last_name => "Savage", :street_address => "65 Thone Street", :city => "Kimbriki", :state => "NSW", :postcode => "2429", :email => "Daniel.N.Savage@dodgit.com", :birthday => "1960/1/15 00:00:00" | ||
| 136 | Person.create :gender => "male", :first_name => "Jonathan", :middle_initial => "F", :last_name => "Schofield", :street_address => "39 Mnimbah Road", :city => "Nelson Bay", :state => "NSW", :postcode => "2315", :email => "Jonathan.F.Schofield@mailinator.com", :birthday => "1960/1/18 00:00:00" | ||
| 137 | Person.create :gender => "female", :first_name => "Rachel", :middle_initial => "L", :last_name => "Sanderson", :street_address => "96 Devon Street", :city => "Marleston Dc", :state => "SA", :postcode => "5033", :email => "Rachel.L.Sanderson@pookmail.com", :birthday => "1968/1/17 00:00:00" | ||
| 138 | Person.create :gender => "female", :first_name => "Grace", :middle_initial => "B", :last_name => "Goodwin", :street_address => "30 Noalimba Avenue", :city => "Camerons Creek", :state => "NSW", :postcode => "2359", :email => "Grace.B.Goodwin@pookmail.com", :birthday => "1957/5/5 00:00:00" | ||
| 139 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "R", :last_name => "Clements", :street_address => "39 Cunningham Street", :city => "Beilba", :state => "QLD", :postcode => "4454", :email => "Shannon.R.Clements@dodgit.com", :birthday => "1967/5/27 00:00:00" | ||
| 140 | Person.create :gender => "female", :first_name => "Jade", :middle_initial => "B", :last_name => "Archer", :street_address => "87 McKillop Street", :city => "Waterloo", :state => "VIC", :postcode => "3373", :email => "Jade.B.Archer@pookmail.com", :birthday => "1944/7/31 00:00:00" | ||
| 141 | Person.create :gender => "female", :first_name => "Imogen", :middle_initial => "B", :last_name => "Mitchell", :street_address => "1 Farrar Parade", :city => "Grey", :state => "WA", :postcode => "6521", :email => "Imogen.B.Mitchell@pookmail.com", :birthday => "1965/1/15 00:00:00" | ||
| 142 | Person.create :gender => "male", :first_name => "Joseph", :middle_initial => "N", :last_name => "Iqbal", :street_address => "44 Dabinett Road", :city => "Teal Flat", :state => "SA", :postcode => "5238", :email => "Joseph.N.Iqbal@trashymail.com", :birthday => "1947/3/28 00:00:00" | ||
| 143 | Person.create :gender => "male", :first_name => "Harry", :middle_initial => "B", :last_name => "Mills", :street_address => "86 Faunce Crescent", :city => "Tharbogang", :state => "NSW", :postcode => "2680", :email => "Harry.B.Mills@pookmail.com", :birthday => "1964/1/29 00:00:00" | ||
| 144 | Person.create :gender => "female", :first_name => "Mia", :middle_initial => "T", :last_name => "Gould", :street_address => "90 Argyle Street", :city => "Tugrabakh", :state => "NSW", :postcode => "2422", :email => "Mia.T.Gould@dodgit.com", :birthday => "1965/1/10 00:00:00" | ||
| 145 | Person.create :gender => "female", :first_name => "Grace", :middle_initial => "E", :last_name => "Thompson", :street_address => "68 Thomas Lane", :city => "Roxburgh Park", :state => "VIC", :postcode => "3064", :email => "Grace.E.Thompson@pookmail.com", :birthday => "1940/2/1 00:00:00" | ||
| 146 | Person.create :gender => "male", :first_name => "Dylan", :middle_initial => "L", :last_name => "Franklin", :street_address => "3 Elizabeth Street", :city => "Widgee Crossing North", :state => "QLD", :postcode => "4570", :email => "Dylan.L.Franklin@trashymail.com", :birthday => "1949/11/22 00:00:00" | ||
| 147 | Person.create :gender => "male", :first_name => "Kieran", :middle_initial => "A", :last_name => "Atkins", :street_address => "88 Peninsula Drive", :city => "Illawong", :state => "NSW", :postcode => "2234", :email => "Kieran.A.Atkins@spambob.com", :birthday => "1962/2/7 00:00:00" | ||
| 148 | Person.create :gender => "male", :first_name => "Aidan", :middle_initial => "E", :last_name => "Carroll", :street_address => "95 Wallis Street", :city => "Darling Point", :state => "NSW", :postcode => "2027", :email => "Aidan.E.Carroll@dodgit.com", :birthday => "1964/10/4 00:00:00" | ||
| 149 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "L", :last_name => "Carey", :street_address => "40 Cherry Grove", :city => "Scotchtown", :state => "TAS", :postcode => "7330", :email => "Shannon.L.Carey@mailinator.com", :birthday => "1964/2/24 00:00:00" | ||
| 150 | Person.create :gender => "female", :first_name => "Laura", :middle_initial => "A", :last_name => "Taylor", :street_address => "4 Sunnyside Road", :city => "Moorook", :state => "SA", :postcode => "5332", :email => "Laura.A.Taylor@trashymail.com", :birthday => "1961/7/12 00:00:00" | ||
| 151 | Person.create :gender => "male", :first_name => "Gabriel", :middle_initial => "J", :last_name => "Walton", :street_address => "15 Woolnough Road", :city => "Parkside", :state => "SA", :postcode => "5063", :email => "Gabriel.J.Walton@mailinator.com", :birthday => "1947/2/16 00:00:00" | ||
| 152 | Person.create :gender => "female", :first_name => "Abbie", :middle_initial => "T", :last_name => "Heath", :street_address => "42 Creek Street", :city => "Weranga", :state => "QLD", :postcode => "4405", :email => "Abbie.T.Heath@dodgit.com", :birthday => "1956/2/4 00:00:00" | ||
| 153 | Person.create :gender => "female", :first_name => "Scarlett", :middle_initial => "S", :last_name => "Baxter", :street_address => "27 Bellion Drive", :city => "Dunsborough", :state => "WA", :postcode => "6281", :email => "Scarlett.S.Baxter@dodgit.com", :birthday => "1951/1/29 00:00:00" | ||
| 154 | Person.create :gender => "female", :first_name => "Demi", :middle_initial => "B", :last_name => "Harvey", :street_address => "68 Trelawney Street", :city => "Paddington", :state => "NSW", :postcode => "2021", :email => "Demi.B.Harvey@dodgit.com", :birthday => "1957/1/26 00:00:00" | ||
| 155 | Person.create :gender => "male", :first_name => "Oliver", :middle_initial => "H", :last_name => "Lowe", :street_address => "52 Brentwood Drive", :city => "Karron", :state => "QLD", :postcode => "4871", :email => "Oliver.H.Lowe@pookmail.com", :birthday => "1971/3/28 00:00:00" | ||
| 156 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "L", :last_name => "Dobson", :street_address => "63 McLeans Road", :city => "Rawbelle", :state => "QLD", :postcode => "4630", :email => "Jake.L.Dobson@dodgit.com", :birthday => "1977/5/22 00:00:00" | ||
| 157 | Person.create :gender => "female", :first_name => "Elise", :middle_initial => "L", :last_name => "Wells", :street_address => "20 Ocean Street", :city => "Warrego", :state => "NT", :postcode => "0862", :email => "Elise.L.Wells@trashymail.com", :birthday => "1958/6/21 00:00:00" | ||
| 158 | Person.create :gender => "female", :first_name => "Jade", :middle_initial => "F", :last_name => "Knowles", :street_address => "99 Auricht Road", :city => "Greenways", :state => "SA", :postcode => "5272", :email => "Jade.F.Knowles@trashymail.com", :birthday => "1973/1/11 00:00:00" | ||
| 159 | Person.create :gender => "male", :first_name => "Thomas", :middle_initial => "M", :last_name => "Iqbal", :street_address => "3 Commercial Street", :city => "Ashbourne", :state => "VIC", :postcode => "3442", :email => "Thomas.M.Iqbal@spambob.com", :birthday => "1949/11/24 00:00:00" | ||
| 160 | Person.create :gender => "female", :first_name => "Isobel", :middle_initial => "A", :last_name => "Edwards", :street_address => "42 Sale Street", :city => "Orange East", :state => "NSW", :postcode => "2800", :email => "Isobel.A.Edwards@dodgit.com", :birthday => "1967/3/1 00:00:00" | ||
| 161 | Person.create :gender => "male", :first_name => "Ryan", :middle_initial => "P", :last_name => "Brookes", :street_address => "48 Grey Street", :city => "Gascoyne River", :state => "WA", :postcode => "6705", :email => "Ryan.P.Brookes@trashymail.com", :birthday => "1948/1/16 00:00:00" | ||
| 162 | Person.create :gender => "female", :first_name => "Natasha", :middle_initial => "N", :last_name => "Adams", :street_address => "91 Bette McNee Street", :city => "Kunama", :state => "NSW", :postcode => "2730", :email => "Natasha.N.Adams@spambob.com", :birthday => "1973/2/3 00:00:00" | ||
| 163 | Person.create :gender => "female", :first_name => "Demi", :middle_initial => "A", :last_name => "Tyler", :street_address => "68 Kooljak Rd", :city => "Reinscourt", :state => "WA", :postcode => "6280", :email => "Demi.A.Tyler@spambob.com", :birthday => "1944/2/6 00:00:00" | ||
| 164 | Person.create :gender => "male", :first_name => "Nicholas", :middle_initial => "E", :last_name => "Bishop", :street_address => "23 Glenpark Road", :city => "Corindi Beach", :state => "NSW", :postcode => "2456", :email => "Nicholas.E.Bishop@mailinator.com", :birthday => "1958/10/26 00:00:00" | ||
| 165 | Person.create :gender => "male", :first_name => "Sean", :middle_initial => "D", :last_name => "Dickinson", :street_address => "37 McKillop Street", :city => "Great Western", :state => "VIC", :postcode => "3377", :email => "Sean.D.Dickinson@spambob.com", :birthday => "1984/2/17 00:00:00" | ||
| 166 | Person.create :gender => "female", :first_name => "Kayleigh", :middle_initial => "D", :last_name => "Marsden", :street_address => "28 Jacabina Court", :city => "Thirroul", :state => "NSW", :postcode => "2515", :email => "Kayleigh.D.Marsden@trashymail.com", :birthday => "1972/12/17 00:00:00" | ||
| 167 | Person.create :gender => "female", :first_name => "Keira", :middle_initial => "B", :last_name => "Nicholls", :street_address => "79 Kerma Crescent", :city => "Rydal", :state => "NSW", :postcode => "2790", :email => "Keira.B.Nicholls@dodgit.com", :birthday => "1960/5/8 00:00:00" | ||
| 168 | Person.create :gender => "female", :first_name => "Imogen", :middle_initial => "R", :last_name => "Ellis", :street_address => "49 Nerrigundah Drive", :city => "Bayles", :state => "VIC", :postcode => "3981", :email => "Imogen.R.Ellis@pookmail.com", :birthday => "1959/10/12 00:00:00" | ||
| 169 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "S", :last_name => "O'Connor", :street_address => "62 Kerma Crescent", :city => "Blackmans Flat", :state => "NSW", :postcode => "2790", :email => "Zachary.S.OConnor@pookmail.com", :birthday => "1957/8/3 00:00:00" | ||
| 170 | Person.create :gender => "male", :first_name => "Peter", :middle_initial => "J", :last_name => "Leach", :street_address => "22 Farrar Parade", :city => "Kadathinni", :state => "WA", :postcode => "6519", :email => "Peter.J.Leach@spambob.com", :birthday => "1981/4/22 00:00:00" | ||
| 171 | Person.create :gender => "male", :first_name => "Joshua", :middle_initial => "M", :last_name => "Brennan", :street_address => "22 Bourke Crescent", :city => "Antwerp", :state => "VIC", :postcode => "3414", :email => "Joshua.M.Brennan@trashymail.com", :birthday => "1982/10/13 00:00:00" | ||
| 172 | Person.create :gender => "female", :first_name => "Jade", :middle_initial => "C", :last_name => "Martin", :street_address => "89 Nandewar Street", :city => "Riverside", :state => "NSW", :postcode => "2444", :email => "Jade.C.Martin@spambob.com", :birthday => "1985/8/5 00:00:00" | ||
| 173 | Person.create :gender => "male", :first_name => "Isaac", :middle_initial => "D", :last_name => "Wyatt", :street_address => "14 Ross Street", :city => "Tallai", :state => "QLD", :postcode => "4213", :email => "Isaac.D.Wyatt@pookmail.com", :birthday => "1976/10/18 00:00:00" | ||
| 174 | Person.create :gender => "male", :first_name => "Liam", :middle_initial => "V", :last_name => "Knight", :street_address => "53 Farrar Parade", :city => "Badgingarra", :state => "WA", :postcode => "6521", :email => "Liam.V.Knight@spambob.com", :birthday => "1952/6/3 00:00:00" | ||
| 175 | Person.create :gender => "male", :first_name => "Corey", :middle_initial => "A", :last_name => "Davey", :street_address => "33 Marley Point Road", :city => "Buchan South", :state => "VIC", :postcode => "3885", :email => "Corey.A.Davey@dodgit.com", :birthday => "1952/2/6 00:00:00" | ||
| 176 | Person.create :gender => "female", :first_name => "Nicole", :middle_initial => "E", :last_name => "Morgan", :street_address => "63 Foreshore Road", :city => "Boya", :state => "WA", :postcode => "6056", :email => "Nicole.E.Morgan@trashymail.com", :birthday => "1941/6/9 00:00:00" | ||
| 177 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "J", :last_name => "Griffin", :street_address => "30 Normans Road", :city => "Wando Bridge", :state => "VIC", :postcode => "3312", :email => "Tegan.J.Griffin@spambob.com", :birthday => "1978/11/27 00:00:00" | ||
| 178 | Person.create :gender => "male", :first_name => "George", :middle_initial => "M", :last_name => "Watts", :street_address => "73 Buoro Street", :city => "Hampden", :state => "QLD", :postcode => "4741", :email => "George.M.Watts@spambob.com", :birthday => "1950/4/17 00:00:00" | ||
| 179 | Person.create :gender => "male", :first_name => "Gabriel", :middle_initial => "I", :last_name => "Clements", :street_address => "35 Boonah Qld", :city => "Gregors Creek", :state => "QLD", :postcode => "4313", :email => "Gabriel.I.Clements@trashymail.com", :birthday => "1964/2/8 00:00:00" | ||
| 180 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "Z", :last_name => "Randall", :street_address => "90 Tanner Street", :city => "Avoca", :state => "QLD", :postcode => "4670", :email => "Sam.Z.Randall@spambob.com", :birthday => "1975/9/25 00:00:00" | ||
| 181 | Person.create :gender => "male", :first_name => "Joshua", :middle_initial => "M", :last_name => "Cooper", :street_address => "13 Mendooran Road", :city => "Coolbaggie", :state => "NSW", :postcode => "2830", :email => "Joshua.M.Cooper@pookmail.com", :birthday => "1978/12/24 00:00:00" | ||
| 182 | Person.create :gender => "female", :first_name => "Sophie", :middle_initial => "P", :last_name => "Barton", :street_address => "56 Harris Street", :city => "Homewood", :state => "VIC", :postcode => "3717", :email => "Sophie.P.Barton@spambob.com", :birthday => "1977/8/5 00:00:00" | ||
| 183 | Person.create :gender => "female", :first_name => "Poppy", :middle_initial => "B", :last_name => "Dennis", :street_address => "76 Point Walter Road", :city => "Fremantle", :state => "WA", :postcode => "6160", :email => "Poppy.B.Dennis@spambob.com", :birthday => "1944/9/2 00:00:00" | ||
| 184 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "E", :last_name => "Weston", :street_address => "76 Friar John Way", :city => "Coodanup", :state => "WA", :postcode => "6210", :email => "Maddison.E.Weston@pookmail.com", :birthday => "1952/8/30 00:00:00" | ||
| 185 | Person.create :gender => "male", :first_name => "Mohammed", :middle_initial => "H", :last_name => "Rice", :street_address => "39 Sinclair Street", :city => "Dowling", :state => "SA", :postcode => "5555", :email => "Mohammed.H.Rice@trashymail.com", :birthday => "1963/5/12 00:00:00" | ||
| 186 | Person.create :gender => "female", :first_name => "Millie", :middle_initial => "R", :last_name => "Mills", :street_address => "52 Horsington Street", :city => "Laburnum", :state => "VIC", :postcode => "3130", :email => "Millie.R.Mills@mailinator.com", :birthday => "1957/5/12 00:00:00" | ||
| 187 | Person.create :gender => "male", :first_name => "Jayden", :middle_initial => "G", :last_name => "Bull", :street_address => "14 Wollombi Street", :city => "Greenlands", :state => "NSW", :postcode => "2330", :email => "Jayden.G.Bull@trashymail.com", :birthday => "1957/9/25 00:00:00" | ||
| 188 | Person.create :gender => "female", :first_name => "Danielle", :middle_initial => "L", :last_name => "Fisher", :street_address => "47 Commercial Street", :city => "Monegeetta", :state => "VIC", :postcode => "3433", :email => "Danielle.L.Fisher@dodgit.com", :birthday => "1984/3/29 00:00:00" | ||
| 189 | Person.create :gender => "male", :first_name => "Mason", :middle_initial => "S", :last_name => "Rowe", :street_address => "23 Correa Place", :city => "Archer", :state => "NT", :postcode => "0830", :email => "Mason.S.Rowe@trashymail.com", :birthday => "1983/3/3 00:00:00" | ||
| 190 | Person.create :gender => "female", :first_name => "Amber", :middle_initial => "B", :last_name => "Morris", :street_address => "22 Maintongoon Road", :city => "Yallourn North", :state => "VIC", :postcode => "3825", :email => "Amber.B.Morris@spambob.com", :birthday => "1982/10/17 00:00:00" | ||
| 191 | Person.create :gender => "male", :first_name => "Mohammed", :middle_initial => "P", :last_name => "Fry", :street_address => "70 Carlisle Street", :city => "Katamatite", :state => "VIC", :postcode => "3649", :email => "Mohammed.P.Fry@dodgit.com", :birthday => "1944/5/10 00:00:00" | ||
| 192 | Person.create :gender => "male", :first_name => "Elliot", :middle_initial => "C", :last_name => "Burton", :street_address => "34 Magnolia Drive", :city => "Hurstville", :state => "NSW", :postcode => "2220", :email => "Elliot.C.Burton@dodgit.com", :birthday => "1941/8/5 00:00:00" | ||
| 193 | Person.create :gender => "male", :first_name => "Liam", :middle_initial => "K", :last_name => "Turnbull", :street_address => "54 Creek Street", :city => "Silverleigh", :state => "QLD", :postcode => "4401", :email => "Liam.K.Turnbull@trashymail.com", :birthday => "1944/11/8 00:00:00" | ||
| 194 | Person.create :gender => "male", :first_name => "Elliot", :middle_initial => "D", :last_name => "Cartwright", :street_address => "44 Chatsworth Drive", :city => "Kelmscott Dc", :state => "WA", :postcode => "6111", :email => "Elliot.D.Cartwright@dodgit.com", :birthday => "1979/9/7 00:00:00" | ||
| 195 | Person.create :gender => "female", :first_name => "Olivia", :middle_initial => "E", :last_name => "Potts", :street_address => "53 Thomas Lane", :city => "Epping Dc", :state => "VIC", :postcode => "3076", :email => "Olivia.E.Potts@dodgit.com", :birthday => "1947/7/25 00:00:00" | ||
| 196 | Person.create :gender => "male", :first_name => "Jonathan", :middle_initial => "L", :last_name => "Barnett", :street_address => "71 Gilbert Street", :city => "Park Grove", :state => "TAS", :postcode => "7320", :email => "Jonathan.L.Barnett@trashymail.com", :birthday => "1956/1/23 00:00:00" | ||
| 197 | Person.create :gender => "female", :first_name => "Eloise", :middle_initial => "T", :last_name => "Barton", :street_address => "9 Shell Road", :city => "Glenaire", :state => "VIC", :postcode => "3238", :email => "Eloise.T.Barton@trashymail.com", :birthday => "1946/5/17 00:00:00" | ||
| 198 | Person.create :gender => "female", :first_name => "Leah", :middle_initial => "A", :last_name => "Miah", :street_address => "85 Cecil Street", :city => "Blenheim Road", :state => "NSW", :postcode => "2113", :email => "Leah.A.Miah@mailinator.com", :birthday => "1977/9/7 00:00:00" | ||
| 199 | Person.create :gender => "female", :first_name => "Libby", :middle_initial => "J", :last_name => "Wallis", :street_address => "36 Frouds Road", :city => "Mallacoota", :state => "VIC", :postcode => "3892", :email => "Libby.J.Wallis@mailinator.com", :birthday => "1979/9/10 00:00:00" | ||
| 200 | Person.create :gender => "male", :first_name => "Hayden", :middle_initial => "A", :last_name => "Rogers", :street_address => "81 Magnolia Drive", :city => "Hurstville Westfield", :state => "NSW", :postcode => "2220", :email => "Hayden.A.Rogers@pookmail.com", :birthday => "1956/1/24 00:00:00" | ||
| 201 | Person.create :gender => "female", :first_name => "Abby", :middle_initial => "M", :last_name => "Harper", :street_address => "43 Lane Street", :city => "Cotham", :state => "VIC", :postcode => "3101", :email => "Abby.M.Harper@spambob.com", :birthday => "1950/9/16 00:00:00" | ||
| 202 | Person.create :gender => "female", :first_name => "Mollie", :middle_initial => "N", :last_name => "Potter", :street_address => "28 Spring Creek Road", :city => "Labertouche", :state => "VIC", :postcode => "3816", :email => "Mollie.N.Potter@trashymail.com", :birthday => "1952/2/11 00:00:00" | ||
| 203 | Person.create :gender => "female", :first_name => "Rachel", :middle_initial => "A", :last_name => "Pickering", :street_address => "74 McPherson Road", :city => "Thowgla Valley", :state => "VIC", :postcode => "3707", :email => "Rachel.A.Pickering@mailinator.com", :birthday => "1958/2/2 00:00:00" | ||
| 204 | Person.create :gender => "male", :first_name => "Ewan", :middle_initial => "I", :last_name => "Holmes", :street_address => "18 Walpole Avenue", :city => "Nirranda East", :state => "VIC", :postcode => "3268", :email => "Ewan.I.Holmes@mailinator.com", :birthday => "1968/7/23 00:00:00" | ||
| 205 | Person.create :gender => "male", :first_name => "Archie", :middle_initial => "S", :last_name => "Thompson", :street_address => "68 Farrar Parade", :city => "Cataby", :state => "WA", :postcode => "6507", :email => "Archie.S.Thompson@dodgit.com", :birthday => "1984/1/18 00:00:00" | ||
| 206 | Person.create :gender => "female", :first_name => "Tilly", :middle_initial => "R", :last_name => "Osborne", :street_address => "86 Butler Crescent", :city => "Mount View", :state => "NSW", :postcode => "2325", :email => "Tilly.R.Osborne@trashymail.com", :birthday => "1960/11/15 00:00:00" | ||
| 207 | Person.create :gender => "female", :first_name => "Kate", :middle_initial => "K", :last_name => "Nelson", :street_address => "91 Sale Street", :city => "Borenore", :state => "NSW", :postcode => "2800", :email => "Kate.K.Nelson@mailinator.com", :birthday => "1959/6/2 00:00:00" | ||
| 208 | Person.create :gender => "male", :first_name => "Spencer", :middle_initial => "S", :last_name => "Brooks", :street_address => "71 Walder Crescent", :city => "Marmor", :state => "QLD", :postcode => "4702", :email => "Spencer.S.Brooks@spambob.com", :birthday => "1966/5/9 00:00:00" | ||
| 209 | Person.create :gender => "female", :first_name => "Kiera", :middle_initial => "J", :last_name => "Wyatt", :street_address => "52 Yulara Drive", :city => "Nyirripi", :state => "NT", :postcode => "0872", :email => "Kiera.J.Wyatt@spambob.com", :birthday => "1952/5/5 00:00:00" | ||
| 210 | Person.create :gender => "male", :first_name => "Hayden", :middle_initial => "A", :last_name => "Hart", :street_address => "94 Devon Street", :city => "Outer Harbor", :state => "SA", :postcode => "5018", :email => "Hayden.A.Hart@mailinator.com", :birthday => "1970/7/4 00:00:00" | ||
| 211 | Person.create :gender => "male", :first_name => "Kian", :middle_initial => "A", :last_name => "Chadwick", :street_address => "95 Ashton Road", :city => "Yoting", :state => "WA", :postcode => "6383", :email => "Kian.A.Chadwick@spambob.com", :birthday => "1961/1/12 00:00:00" | ||
| 212 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "L", :last_name => "Burrows", :street_address => "63 Ross Street", :city => "Nerang Dc", :state => "QLD", :postcode => "4211", :email => "Tegan.L.Burrows@dodgit.com", :birthday => "1959/9/8 00:00:00" | ||
| 213 | Person.create :gender => "female", :first_name => "Chloe", :middle_initial => "O", :last_name => "Norris", :street_address => "30 Jones Road", :city => "Forest Lake", :state => "QLD", :postcode => "4078", :email => "Chloe.O.Norris@trashymail.com", :birthday => "1970/4/15 00:00:00" | ||
| 214 | Person.create :gender => "female", :first_name => "Tilly", :middle_initial => "M", :last_name => "Cross", :street_address => "41 Harris Street", :city => "Towong Upper", :state => "VIC", :postcode => "3707", :email => "Tilly.M.Cross@dodgit.com", :birthday => "1952/9/2 00:00:00" | ||
| 215 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "I", :last_name => "Sinclair", :street_address => "73 Jacolite Street", :city => "Darlington", :state => "WA", :postcode => "6070", :email => "Jacob.I.Sinclair@spambob.com", :birthday => "1971/4/15 00:00:00" | ||
| 216 | Person.create :gender => "male", :first_name => "John", :middle_initial => "S", :last_name => "Lucas", :street_address => "61 Dossiter Street", :city => "Andover", :state => "TAS", :postcode => "7120", :email => "John.S.Lucas@dodgit.com", :birthday => "1971/4/12 00:00:00" | ||
| 217 | Person.create :gender => "female", :first_name => "Morgan", :middle_initial => "A", :last_name => "Richardson", :street_address => "29 Taylor Street", :city => "Barmah", :state => "VIC", :postcode => "3639", :email => "Morgan.A.Richardson@dodgit.com", :birthday => "1983/12/10 00:00:00" | ||
| 218 | Person.create :gender => "female", :first_name => "Niamh", :middle_initial => "J", :last_name => "Holmes", :street_address => "33 Acheron Road", :city => "Morwell", :state => "VIC", :postcode => "3840", :email => "Niamh.J.Holmes@trashymail.com", :birthday => "1950/4/29 00:00:00" | ||
| 219 | Person.create :gender => "female", :first_name => "Summer", :middle_initial => "J", :last_name => "Grant", :street_address => "51 Milbrodale Road", :city => "Roughit", :state => "NSW", :postcode => "2330", :email => "Summer.J.Grant@spambob.com", :birthday => "1951/3/1 00:00:00" | ||
| 220 | Person.create :gender => "female", :first_name => "Rosie", :middle_initial => "B", :last_name => "Holloway", :street_address => "7 Ross Smith Avenue", :city => "Darwin", :state => "NT", :postcode => "0800", :email => "Rosie.B.Holloway@pookmail.com", :birthday => "1951/11/27 00:00:00" | ||
| 221 | Person.create :gender => "male", :first_name => "Harvey", :middle_initial => "S", :last_name => "Boyle", :street_address => "62 Ridge Road", :city => "Lowmead", :state => "QLD", :postcode => "4676", :email => "Harvey.S.Boyle@spambob.com", :birthday => "1984/9/3 00:00:00" | ||
| 222 | Person.create :gender => "female", :first_name => "Aimee", :middle_initial => "H", :last_name => "May", :street_address => "14 Goebels Road", :city => "Merryvale", :state => "QLD", :postcode => "4340", :email => "Aimee.H.May@pookmail.com", :birthday => "1949/4/12 00:00:00" | ||
| 223 | Person.create :gender => "male", :first_name => "Ryan", :middle_initial => "E", :last_name => "Connor", :street_address => "72 Boobialla Street", :city => "Sandigo", :state => "NSW", :postcode => "2700", :email => "Ryan.E.Connor@spambob.com", :birthday => "1974/11/29 00:00:00" | ||
| 224 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "C", :last_name => "Bevan", :street_address => "8 Patton Street", :city => "Ashwood", :state => "VIC", :postcode => "3147", :email => "Shannon.C.Bevan@mailinator.com", :birthday => "1977/5/23 00:00:00" | ||
| 225 | Person.create :gender => "male", :first_name => "Freddie", :middle_initial => "B", :last_name => "Fisher", :street_address => "46 Nerrigundah Drive", :city => "Cranbourne West", :state => "VIC", :postcode => "3977", :email => "Freddie.B.Fisher@trashymail.com", :birthday => "1959/12/7 00:00:00" | ||
| 226 | Person.create :gender => "male", :first_name => "Joel", :middle_initial => "C", :last_name => "Manning", :street_address => "16 Alfred Street", :city => "Bandy Creek", :state => "WA", :postcode => "6450", :email => "Joel.C.Manning@spambob.com", :birthday => "1945/12/2 00:00:00" | ||
| 227 | Person.create :gender => "male", :first_name => "Adam", :middle_initial => "A", :last_name => "Fraser", :street_address => "77 Lapko Road", :city => "Cowalellup", :state => "WA", :postcode => "6336", :email => "Adam.A.Fraser@trashymail.com", :birthday => "1952/4/14 00:00:00" | ||
| 228 | Person.create :gender => "male", :first_name => "Ben", :middle_initial => "N", :last_name => "McCarthy", :street_address => "86 Warren Avenue", :city => "Catherine Hill Bay", :state => "NSW", :postcode => "2281", :email => "Ben.N.McCarthy@trashymail.com", :birthday => "1983/5/9 00:00:00" | ||
| 229 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "F", :last_name => "Johnson", :street_address => "81 Weigall Avenue", :city => "Alma", :state => "SA", :postcode => "5401", :email => "Zachary.F.Johnson@mailinator.com", :birthday => "1947/11/23 00:00:00" | ||
| 230 | Person.create :gender => "female", :first_name => "Morgan", :middle_initial => "M", :last_name => "Coleman", :street_address => "80 Glen William Road", :city => "Croydon", :state => "QLD", :postcode => "4871", :email => "Morgan.M.Coleman@trashymail.com", :birthday => "1973/10/26 00:00:00" | ||
| 231 | Person.create :gender => "male", :first_name => "Jay", :middle_initial => "E", :last_name => "Craig", :street_address => "43 Loris Way", :city => "Hillside", :state => "WA", :postcode => "6312", :email => "Jay.E.Craig@mailinator.com", :birthday => "1959/9/17 00:00:00" | ||
| 232 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "J", :last_name => "Elliott", :street_address => "51 Boobialla Street", :city => "Widgiewa", :state => "NSW", :postcode => "2700", :email => "Ava.J.Elliott@spambob.com", :birthday => "1949/5/20 00:00:00" | ||
| 233 | Person.create :gender => "male", :first_name => "William", :middle_initial => "P", :last_name => "Nelson", :street_address => "36 Stanley Drive", :city => "Laguna Quays", :state => "QLD", :postcode => "4800", :email => "William.P.Nelson@dodgit.com", :birthday => "1962/6/15 00:00:00" | ||
| 234 | Person.create :gender => "male", :first_name => "Ryan", :middle_initial => "K", :last_name => "Palmer", :street_address => "47 Anderson Street", :city => "Bulwer", :state => "QLD", :postcode => "4025", :email => "Ryan.K.Palmer@dodgit.com", :birthday => "1940/7/11 00:00:00" | ||
| 235 | Person.create :gender => "female", :first_name => "Isabella", :middle_initial => "C", :last_name => "Harding", :street_address => "38 Argyle Street", :city => "Mernot", :state => "NSW", :postcode => "2422", :email => "Isabella.C.Harding@trashymail.com", :birthday => "1985/7/23 00:00:00" | ||
| 236 | Person.create :gender => "female", :first_name => "Samantha", :middle_initial => "C", :last_name => "Price", :street_address => "53 Inglewood Court", :city => "North Blackwood", :state => "VIC", :postcode => "3458", :email => "Samantha.C.Price@mailinator.com", :birthday => "1968/7/30 00:00:00" | ||
| 237 | Person.create :gender => "male", :first_name => "Samuel", :middle_initial => "R", :last_name => "Hayes", :street_address => "25 Wilson Street", :city => "Nyarrin", :state => "VIC", :postcode => "3533", :email => "Samuel.R.Hayes@pookmail.com", :birthday => "1968/11/8 00:00:00" | ||
| 238 | Person.create :gender => "male", :first_name => "Harry", :middle_initial => "H", :last_name => "Hurst", :street_address => "55 Bapaume Road", :city => "Pechey", :state => "QLD", :postcode => "4352", :email => "Harry.H.Hurst@dodgit.com", :birthday => "1983/3/1 00:00:00" | ||
| 239 | Person.create :gender => "male", :first_name => "Tyler", :middle_initial => "R", :last_name => "Hewitt", :street_address => "2 Ronald Crescent", :city => "River Ranch", :state => "QLD", :postcode => "4680", :email => "Tyler.R.Hewitt@spambob.com", :birthday => "1957/5/9 00:00:00" | ||
| 240 | Person.create :gender => "female", :first_name => "Olivia", :middle_initial => "A", :last_name => "McCarthy", :street_address => "4 Ross Street", :city => "Southern Lamington", :state => "QLD", :postcode => "4211", :email => "Olivia.A.McCarthy@dodgit.com", :birthday => "1981/9/2 00:00:00" | ||
| 241 | Person.create :gender => "female", :first_name => "Eve", :middle_initial => "M", :last_name => "Price", :street_address => "69 Normans Road", :city => "Brit Brit", :state => "VIC", :postcode => "3315", :email => "Eve.M.Price@trashymail.com", :birthday => "1940/1/10 00:00:00" | ||
| 242 | Person.create :gender => "female", :first_name => "Niamh", :middle_initial => "M", :last_name => "Douglas", :street_address => "39 Crofts Road", :city => "Simpsons Creek", :state => "VIC", :postcode => "3888", :email => "Niamh.M.Douglas@spambob.com", :birthday => "1947/4/7 00:00:00" | ||
| 243 | Person.create :gender => "male", :first_name => "Muhammad", :middle_initial => "G", :last_name => "Dobson", :street_address => "12 Glenpark Road", :city => "Bayldon", :state => "NSW", :postcode => "2452", :email => "Muhammad.G.Dobson@pookmail.com", :birthday => "1960/8/30 00:00:00" | ||
| 244 | Person.create :gender => "female", :first_name => "Jessica", :middle_initial => "J", :last_name => "Webb", :street_address => "3 Myrtle Street", :city => "Almonds", :state => "VIC", :postcode => "3727", :email => "Jessica.J.Webb@trashymail.com", :birthday => "1952/6/10 00:00:00" | ||
| 245 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "L", :last_name => "Holland", :street_address => "48 Porana Place", :city => "Nugadong", :state => "WA", :postcode => "6609", :email => "Zachary.L.Holland@mailinator.com", :birthday => "1984/3/13 00:00:00" | ||
| 246 | Person.create :gender => "male", :first_name => "Scott", :middle_initial => "A", :last_name => "Hyde", :street_address => "95 Spencer Street", :city => "Tin Can Bay", :state => "QLD", :postcode => "4580", :email => "Scott.A.Hyde@mailinator.com", :birthday => "1942/5/4 00:00:00" | ||
| 247 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "P", :last_name => "Myers", :street_address => "9 Rose Street", :city => "Narre Warren", :state => "VIC", :postcode => "3805", :email => "Shannon.P.Myers@mailinator.com", :birthday => "1955/3/2 00:00:00" | ||
| 248 | Person.create :gender => "female", :first_name => "Lauren", :middle_initial => "H", :last_name => "Whitehouse", :street_address => "47 Begley Street", :city => "Herberton", :state => "QLD", :postcode => "4887", :email => "Lauren.H.Whitehouse@trashymail.com", :birthday => "1975/3/10 00:00:00" | ||
| 249 | Person.create :gender => "female", :first_name => "Ella", :middle_initial => "L", :last_name => "George", :street_address => "42 Chatsworth Road", :city => "Kippenduff", :state => "NSW", :postcode => "2469", :email => "Ella.L.George@spambob.com", :birthday => "1945/12/8 00:00:00" | ||
| 250 | Person.create :gender => "female", :first_name => "Lilly", :middle_initial => "L", :last_name => "Morton", :street_address => "92 Railway Street", :city => "Greenmount", :state => "QLD", :postcode => "4359", :email => "Lilly.L.Morton@spambob.com", :birthday => "1980/12/9 00:00:00" | ||
| 251 | Person.create :gender => "male", :first_name => "Jamie", :middle_initial => "I", :last_name => "Rose", :street_address => "35 Benny Street", :city => "Miandetta", :state => "TAS", :postcode => "7310", :email => "Jamie.I.Rose@mailinator.com", :birthday => "1952/7/24 00:00:00" | ||
| 252 | Person.create :gender => "female", :first_name => "Millie", :middle_initial => "D", :last_name => "Daniels", :street_address => "52 Point Walter Road", :city => "Naval Base", :state => "WA", :postcode => "6165", :email => "Millie.D.Daniels@trashymail.com", :birthday => "1962/5/3 00:00:00" | ||
| 253 | Person.create :gender => "female", :first_name => "Eva", :middle_initial => "G", :last_name => "Banks", :street_address => "21 Ugoa Street", :city => "Boomerang Beach", :state => "NSW", :postcode => "2428", :email => "Eva.G.Banks@spambob.com", :birthday => "1945/4/3 00:00:00" | ||
| 254 | Person.create :gender => "male", :first_name => "Nathan", :middle_initial => "L", :last_name => "Collins", :street_address => "63 Tapleys Hill Road", :city => "Paralowie", :state => "SA", :postcode => "5108", :email => "Nathan.L.Collins@spambob.com", :birthday => "1959/12/1 00:00:00" | ||
| 255 | Person.create :gender => "female", :first_name => "Imogen", :middle_initial => "H", :last_name => "Rees", :street_address => "85 Forrest Road", :city => "Bourke", :state => "NSW", :postcode => "2840", :email => "Imogen.H.Rees@spambob.com", :birthday => "1949/7/20 00:00:00" | ||
| 256 | Person.create :gender => "male", :first_name => "Adam", :middle_initial => "L", :last_name => "Lord", :street_address => "60 Trelawney Street", :city => "Mascot", :state => "NSW", :postcode => "2020", :email => "Adam.L.Lord@mailinator.com", :birthday => "1973/12/31 00:00:00" | ||
| 257 | Person.create :gender => "male", :first_name => "Alexander", :middle_initial => "I", :last_name => "Stone", :street_address => "71 Buoro Street", :city => "Pinnacle", :state => "QLD", :postcode => "4741", :email => "Alexander.I.Stone@mailinator.com", :birthday => "1949/4/26 00:00:00" | ||
| 258 | Person.create :gender => "female", :first_name => "Bethany", :middle_initial => "L", :last_name => "Dodd", :street_address => "98 Arthur Street", :city => "Mount Aquila", :state => "NSW", :postcode => "2820", :email => "Bethany.L.Dodd@pookmail.com", :birthday => "1963/11/25 00:00:00" | ||
| 259 | Person.create :gender => "female", :first_name => "Jessica", :middle_initial => "R", :last_name => "Marsden", :street_address => "43 Railway Avenue", :city => "Taripta", :state => "VIC", :postcode => "3620", :email => "Jessica.R.Marsden@trashymail.com", :birthday => "1955/11/17 00:00:00" | ||
| 260 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "R", :last_name => "Pope", :street_address => "65 Faunce Crescent", :city => "Warburn", :state => "NSW", :postcode => "2680", :email => "Owen.R.Pope@dodgit.com", :birthday => "1976/7/12 00:00:00" | ||
| 261 | Person.create :gender => "female", :first_name => "Aaliyah", :middle_initial => "J", :last_name => "Howard", :street_address => "21 Armstrong Street", :city => "Murray Downs", :state => "NSW", :postcode => "3585", :email => "Aaliyah.J.Howard@pookmail.com", :birthday => "1943/7/9 00:00:00" | ||
| 262 | Person.create :gender => "female", :first_name => "Lucy", :middle_initial => "D", :last_name => "Turnbull", :street_address => "31 Gaffney Street", :city => "Middle Park", :state => "VIC", :postcode => "3206", :email => "Lucy.D.Turnbull@dodgit.com", :birthday => "1959/10/29 00:00:00" | ||
| 263 | Person.create :gender => "female", :first_name => "Ella", :middle_initial => "G", :last_name => "Potts", :street_address => "12 George Street", :city => "Lumeah", :state => "QLD", :postcode => "4478", :email => "Ella.G.Potts@trashymail.com", :birthday => "1974/1/31 00:00:00" | ||
| 264 | Person.create :gender => "male", :first_name => "Edward", :middle_initial => "H", :last_name => "Ali", :street_address => "17 Sale Street", :city => "Lower Lewis Ponds", :state => "NSW", :postcode => "2800", :email => "Edward.H.Ali@dodgit.com", :birthday => "1951/9/11 00:00:00" | ||
| 265 | Person.create :gender => "male", :first_name => "Tyler", :middle_initial => "K", :last_name => "Shaw", :street_address => "54 Jones Road", :city => "Richlands Dc", :state => "QLD", :postcode => "4077", :email => "Tyler.K.Shaw@pookmail.com", :birthday => "1974/4/1 00:00:00" | ||
| 266 | Person.create :gender => "female", :first_name => "Summer", :middle_initial => "K", :last_name => "Hopkins", :street_address => "90 Woodlands Avenue", :city => "Berrilee", :state => "NSW", :postcode => "2159", :email => "Summer.K.Hopkins@pookmail.com", :birthday => "1984/10/29 00:00:00" | ||
| 267 | Person.create :gender => "male", :first_name => "Callum", :middle_initial => "Y", :last_name => "Carr", :street_address => "77 Jacabina Court", :city => "Mangerton", :state => "NSW", :postcode => "2500", :email => "Callum.Y.Carr@pookmail.com", :birthday => "1948/1/7 00:00:00" | ||
| 268 | Person.create :gender => "female", :first_name => "Freya", :middle_initial => "O", :last_name => "O'onnor", :street_address => "75 Capper Street", :city => "The Limits", :state => "QLD", :postcode => "4625", :email => "Freya.O.O'onnor@pookmail.com", :birthday => "1973/4/12 00:00:00" | ||
| 269 | Person.create :gender => "male", :first_name => "Sean", :middle_initial => "A", :last_name => "Burton", :street_address => "91 Kogil Street", :city => "Narrabri West", :state => "NSW", :postcode => "2390", :email => "Sean.A.Burton@dodgit.com", :birthday => "1943/5/4 00:00:00" | ||
| 270 | Person.create :gender => "male", :first_name => "David", :middle_initial => "A", :last_name => "Nicholls", :street_address => "3 Wright Street", :city => "Kulangoor", :state => "QLD", :postcode => "4560", :email => "David.A.Nicholls@pookmail.com", :birthday => "1943/2/26 00:00:00" | ||
| 271 | Person.create :gender => "male", :first_name => "David", :middle_initial => "M", :last_name => "Brady", :street_address => "39 Woerdens Road", :city => "Manobalai", :state => "NSW", :postcode => "2333", :email => "David.M.Brady@pookmail.com", :birthday => "1962/1/19 00:00:00" | ||
| 272 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "G", :last_name => "Pearson", :street_address => "87 Carolina Park Road", :city => "Umina Beach", :state => "NSW", :postcode => "2257", :email => "Isabelle.G.Pearson@dodgit.com", :birthday => "1981/5/31 00:00:00" | ||
| 273 | Person.create :gender => "male", :first_name => "Mason", :middle_initial => "L", :last_name => "Kent", :street_address => "22 Bailey Street", :city => "Tower Hill", :state => "VIC", :postcode => "3283", :email => "Mason.L.Kent@pookmail.com", :birthday => "1964/2/18 00:00:00" | ||
| 274 | Person.create :gender => "male", :first_name => "Sebastian", :middle_initial => "Z", :last_name => "Stephens", :street_address => "47 Black Point Drive", :city => "Whyalla Playford", :state => "SA", :postcode => "5600", :email => "Sebastian.Z.Stephens@dodgit.com", :birthday => "1960/1/19 00:00:00" | ||
| 275 | Person.create :gender => "female", :first_name => "Chelsea", :middle_initial => "C", :last_name => "Shaw", :street_address => "10 Todd Street", :city => "East Bowes", :state => "WA", :postcode => "6535", :email => "Chelsea.C.Shaw@mailinator.com", :birthday => "1964/2/22 00:00:00" | ||
| 276 | Person.create :gender => "male", :first_name => "Reece", :middle_initial => "C", :last_name => "Webster", :street_address => "33 Banksia Court", :city => "Cambridge", :state => "QLD", :postcode => "4822", :email => "Reece.C.Webster@trashymail.com", :birthday => "1947/6/2 00:00:00" | ||
| 277 | Person.create :gender => "male", :first_name => "Jonathan", :middle_initial => "J", :last_name => "Morris", :street_address => "83 Carolina Park Road", :city => "Koolewong", :state => "NSW", :postcode => "2256", :email => "Jonathan.J.Morris@dodgit.com", :birthday => "1955/7/28 00:00:00" | ||
| 278 | Person.create :gender => "female", :first_name => "Elise", :middle_initial => "L", :last_name => "Scott", :street_address => "88 Chatsworth Drive", :city => "Ascot", :state => "WA", :postcode => "6104", :email => "Elise.L.Scott@pookmail.com", :birthday => "1976/5/11 00:00:00" | ||
| 279 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "R", :last_name => "Simmons", :street_address => "63 Mandible Street", :city => "Mount Isa East", :state => "QLD", :postcode => "4825", :email => "Christopher.R.Simmons@trashymail.com", :birthday => "1955/11/25 00:00:00" | ||
| 280 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "L", :last_name => "Peacock", :street_address => "84 Weemala Avenue", :city => "Canowindra", :state => "NSW", :postcode => "2804", :email => "Tom.L.Peacock@pookmail.com", :birthday => "1954/2/16 00:00:00" | ||
| 281 | Person.create :gender => "female", :first_name => "Ruby", :middle_initial => "S", :last_name => "Atkinson", :street_address => "55 Derry Street", :city => "North Bungunya", :state => "QLD", :postcode => "4494", :email => "Ruby.S.Atkinson@spambob.com", :birthday => "1982/2/4 00:00:00" | ||
| 282 | Person.create :gender => "male", :first_name => "Joel", :middle_initial => "E", :last_name => "Summers", :street_address => "95 Alfred Street", :city => "Leonora", :state => "WA", :postcode => "6438", :email => "Joel.E.Summers@pookmail.com", :birthday => "1965/4/23 00:00:00" | ||
| 283 | Person.create :gender => "female", :first_name => "Rebecca", :middle_initial => "L", :last_name => "Burgess", :street_address => "14 Gloucester Avenue", :city => "West Hindmarsh", :state => "SA", :postcode => "5007", :email => "Rebecca.L.Burgess@mailinator.com", :birthday => "1964/6/19 00:00:00" | ||
| 284 | Person.create :gender => "female", :first_name => "Lola", :middle_initial => "G", :last_name => "Holden", :street_address => "40 Buoro Street", :city => "Yalboroo", :state => "QLD", :postcode => "4741", :email => "Lola.G.Holden@pookmail.com", :birthday => "1952/1/4 00:00:00" | ||
| 285 | Person.create :gender => "male", :first_name => "Louis", :middle_initial => "R", :last_name => "Lees", :street_address => "3 Peninsula Drive", :city => "Engadine", :state => "NSW", :postcode => "2233", :email => "Louis.R.Lees@mailinator.com", :birthday => "1984/3/13 00:00:00" | ||
| 286 | Person.create :gender => "female", :first_name => "Maya", :middle_initial => "H", :last_name => "Moss", :street_address => "27 Buoro Street", :city => "Owens Creek", :state => "QLD", :postcode => "4741", :email => "Maya.H.Moss@dodgit.com", :birthday => "1966/8/27 00:00:00" | ||
| 287 | Person.create :gender => "male", :first_name => "Jude", :middle_initial => "M", :last_name => "Cunningham", :street_address => "18 McKillop Street", :city => "Mena Park", :state => "VIC", :postcode => "3373", :email => "Jude.M.Cunningham@trashymail.com", :birthday => "1954/9/16 00:00:00" | ||
| 288 | Person.create :gender => "male", :first_name => "Cameron", :middle_initial => "L", :last_name => "Johnson", :street_address => "12 Carnegie Avenue", :city => "Buller", :state => "WA", :postcode => "6532", :email => "Cameron.L.Johnson@spambob.com", :birthday => "1958/1/5 00:00:00" | ||
| 289 | Person.create :gender => "female", :first_name => "Freya", :middle_initial => "C", :last_name => "Reed", :street_address => "31 Boughtman Street", :city => "Carnegie", :state => "VIC", :postcode => "3163", :email => "Freya.C.Reed@pookmail.com", :birthday => "1962/3/25 00:00:00" | ||
| 290 | Person.create :gender => "female", :first_name => "Charlotte", :middle_initial => "B", :last_name => "Moore", :street_address => "68 Larissa Court", :city => "Iraak", :state => "VIC", :postcode => "3494", :email => "Charlotte.B.Moore@mailinator.com", :birthday => "1985/2/23 00:00:00" | ||
| 291 | Person.create :gender => "male", :first_name => "Jude", :middle_initial => "S", :last_name => "Bennett", :street_address => "96 Acheron Road", :city => "Wurruk", :state => "VIC", :postcode => "3850", :email => "Jude.S.Bennett@dodgit.com", :birthday => "1974/8/8 00:00:00" | ||
| 292 | Person.create :gender => "female", :first_name => "Isabel", :middle_initial => "C", :last_name => "Hanson", :street_address => "7 McLaughlin Road", :city => "Nukku", :state => "QLD", :postcode => "4306", :email => "Isabel.C.Hanson@trashymail.com", :birthday => "1968/12/1 00:00:00" | ||
| 293 | Person.create :gender => "male", :first_name => "Leo", :middle_initial => "N", :last_name => "West", :street_address => "96 Holthouse Road", :city => "Muston", :state => "SA", :postcode => "5221", :email => "Leo.N.West@trashymail.com", :birthday => "1973/12/18 00:00:00" | ||
| 294 | Person.create :gender => "female", :first_name => "Summer", :middle_initial => "M", :last_name => "Hammond", :street_address => "45 Cambridge Street", :city => "Freemans Reach", :state => "NSW", :postcode => "2756", :email => "Summer.M.Hammond@dodgit.com", :birthday => "1971/2/12 00:00:00" | ||
| 295 | Person.create :gender => "female", :first_name => "Eve", :middle_initial => "H", :last_name => "Jenkins", :street_address => "85 Sydney Road", :city => "Wilpinjong", :state => "NSW", :postcode => "2850", :email => "Eve.H.Jenkins@spambob.com", :birthday => "1957/9/7 00:00:00" | ||
| 296 | Person.create :gender => "male", :first_name => "Luke", :middle_initial => "E", :last_name => "Connor", :street_address => "76 Jacabina Court", :city => "Tanglewood", :state => "NSW", :postcode => "2488", :email => "Luke.E.Connor@dodgit.com", :birthday => "1962/10/2 00:00:00" | ||
| 297 | Person.create :gender => "female", :first_name => "Amy", :middle_initial => "A", :last_name => "Stanley", :street_address => "84 Ghost Hill Road", :city => "East Kurrajong", :state => "NSW", :postcode => "2758", :email => "Amy.A.Stanley@trashymail.com", :birthday => "1974/1/4 00:00:00" | ||
| 298 | Person.create :gender => "female", :first_name => "Jodie", :middle_initial => "R", :last_name => "Johnston", :street_address => "79 South Molle Boulevard", :city => "Nicholson", :state => "QLD", :postcode => "4830", :email => "Jodie.R.Johnston@spambob.com", :birthday => "1974/1/22 00:00:00" | ||
| 299 | Person.create :gender => "male", :first_name => "Spencer", :middle_initial => "N", :last_name => "Dickinson", :street_address => "84 Spring Creek Road", :city => "Brandy Creek", :state => "VIC", :postcode => "3821", :email => "Spencer.N.Dickinson@dodgit.com", :birthday => "1974/10/13 00:00:00" | ||
| 300 | Person.create :gender => "female", :first_name => "Tia", :middle_initial => "F", :last_name => "Nolan", :street_address => "43 Tennyson Road", :city => "Marrickville South", :state => "NSW", :postcode => "2204", :email => "Tia.F.Nolan@dodgit.com", :birthday => "1970/10/8 00:00:00" | ||
| 301 | Person.create :gender => "female", :first_name => "Molly", :middle_initial => "T", :last_name => "Byrne", :street_address => "32 Sale-Heyfield Road", :city => "Berrys Creek", :state => "VIC", :postcode => "3953", :email => "Molly.T.Byrne@trashymail.com", :birthday => "1956/2/27 00:00:00" | ||
| 302 | Person.create :gender => "male", :first_name => "Jonathan", :middle_initial => "L", :last_name => "Allen", :street_address => "73 Round Drive", :city => "Rathmines", :state => "NSW", :postcode => "2283", :email => "Jonathan.L.Allen@dodgit.com", :birthday => "1951/5/17 00:00:00" | ||
| 303 | Person.create :gender => "male", :first_name => "Andrew", :middle_initial => "Y", :last_name => "Vincent", :street_address => "69 Glendonbrook Road", :city => "Camboon", :state => "NSW", :postcode => "2849", :email => "Andrew.Y.Vincent@trashymail.com", :birthday => "1950/11/30 00:00:00" | ||
| 304 | Person.create :gender => "male", :first_name => "Sean", :middle_initial => "H", :last_name => "Perkins", :street_address => "20 Roseda-Tinamba Road", :city => "Bennison", :state => "VIC", :postcode => "3960", :email => "Sean.H.Perkins@spambob.com", :birthday => "1961/11/18 00:00:00" | ||
| 305 | Person.create :gender => "female", :first_name => "Caitlin", :middle_initial => "A", :last_name => "Burrows", :street_address => "75 Souttar Terrace", :city => "Mount Claremont", :state => "WA", :postcode => "6010", :email => "Caitlin.A.Burrows@pookmail.com", :birthday => "1976/12/7 00:00:00" | ||
| 306 | Person.create :gender => "female", :first_name => "Amber", :middle_initial => "J", :last_name => "Booth", :street_address => "17 Milbrodale Road", :city => "Jerrys Plains", :state => "NSW", :postcode => "2330", :email => "Amber.J.Booth@spambob.com", :birthday => "1966/3/27 00:00:00" | ||
| 307 | Person.create :gender => "female", :first_name => "Amelie", :middle_initial => "C", :last_name => "Skinner", :street_address => "26 Adavale Road", :city => "Wowagin", :state => "NSW", :postcode => "2580", :email => "Amelie.C.Skinner@pookmail.com", :birthday => "1967/3/21 00:00:00" | ||
| 308 | Person.create :gender => "female", :first_name => "Maya", :middle_initial => "T", :last_name => "Wall", :street_address => "34 Atkinson Way", :city => "Millstream", :state => "WA", :postcode => "6716", :email => "Maya.T.Wall@trashymail.com", :birthday => "1961/7/12 00:00:00" | ||
| 309 | Person.create :gender => "male", :first_name => "Daniel", :middle_initial => "M", :last_name => "Bird", :street_address => "73 Wallis Street", :city => "Rose Bay North", :state => "NSW", :postcode => "2030", :email => "Daniel.M.Bird@mailinator.com", :birthday => "1976/11/30 00:00:00" | ||
| 310 | Person.create :gender => "male", :first_name => "Evan", :middle_initial => "T", :last_name => "Blackburn", :street_address => "22 Glendonbrook Road", :city => "Bogee", :state => "NSW", :postcode => "2849", :email => "Evan.T.Blackburn@dodgit.com", :birthday => "1955/8/24 00:00:00" | ||
| 311 | Person.create :gender => "female", :first_name => "Imogen", :middle_initial => "J", :last_name => "Burns", :street_address => "37 Goldfields Road", :city => "Cement Mills", :state => "QLD", :postcode => "4352", :email => "Imogen.J.Burns@mailinator.com", :birthday => "1980/1/22 00:00:00" | ||
| 312 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "K", :last_name => "Craig", :street_address => "86 Darwinia Loop", :city => "Tom Price", :state => "WA", :postcode => "6751", :email => "Owen.K.Craig@pookmail.com", :birthday => "1944/7/19 00:00:00" | ||
| 313 | Person.create :gender => "female", :first_name => "Emily", :middle_initial => "T", :last_name => "Elliott", :street_address => "37 Goebels Road", :city => "Blenheim", :state => "QLD", :postcode => "4341", :email => "Emily.T.Elliott@trashymail.com", :birthday => "1965/1/3 00:00:00" | ||
| 314 | Person.create :gender => "female", :first_name => "Maisie", :middle_initial => "T", :last_name => "Johnson", :street_address => "84 Bette McNee Street", :city => "Cunninyeuk", :state => "NSW", :postcode => "2734", :email => "Maisie.T.Johnson@spambob.com", :birthday => "1984/8/16 00:00:00" | ||
| 315 | Person.create :gender => "female", :first_name => "Daisy", :middle_initial => "A", :last_name => "Bryan", :street_address => "65 Frouds Road", :city => "Glen Wills", :state => "VIC", :postcode => "3898", :email => "Daisy.A.Bryan@trashymail.com", :birthday => "1944/7/28 00:00:00" | ||
| 316 | Person.create :gender => "female", :first_name => "Aimee", :middle_initial => "N", :last_name => "Holden", :street_address => "32 Mills Street", :city => "Glen Forbes", :state => "VIC", :postcode => "3990", :email => "Aimee.N.Holden@trashymail.com", :birthday => "1942/3/26 00:00:00" | ||
| 317 | Person.create :gender => "male", :first_name => "Nicholas", :middle_initial => "A", :last_name => "Parkinson", :street_address => "25 Anderson Street", :city => "Zillmere", :state => "QLD", :postcode => "4034", :email => "Nicholas.A.Parkinson@dodgit.com", :birthday => "1952/5/10 00:00:00" | ||
| 318 | Person.create :gender => "male", :first_name => "David", :middle_initial => "K", :last_name => "Hill", :street_address => "56 Jones Road", :city => "Sumner", :state => "QLD", :postcode => "4074", :email => "David.K.Hill@dodgit.com", :birthday => "1947/8/5 00:00:00" | ||
| 319 | Person.create :gender => "female", :first_name => "Molly", :middle_initial => "J", :last_name => "Gough", :street_address => "82 Milbrodale Road", :city => "Reedy Creek", :state => "NSW", :postcode => "2330", :email => "Molly.J.Gough@trashymail.com", :birthday => "1965/6/2 00:00:00" | ||
| 320 | Person.create :gender => "male", :first_name => "Patrick", :middle_initial => "E", :last_name => "Blake", :street_address => "91 Stanley Drive", :city => "Glen Isla", :state => "QLD", :postcode => "4800", :email => "Patrick.E.Blake@pookmail.com", :birthday => "1969/12/20 00:00:00" | ||
| 321 | Person.create :gender => "male", :first_name => "Nathan", :middle_initial => "E", :last_name => "Miles", :street_address => "58 Cherokee Road", :city => "Hepburn Springs", :state => "VIC", :postcode => "3461", :email => "Nathan.E.Miles@trashymail.com", :birthday => "1967/7/5 00:00:00" | ||
| 322 | Person.create :gender => "female", :first_name => "Alisha", :middle_initial => "A", :last_name => "Manning", :street_address => "28 Begley Street", :city => "Bloomfield", :state => "QLD", :postcode => "4895", :email => "Alisha.A.Manning@trashymail.com", :birthday => "1944/4/13 00:00:00" | ||
| 323 | Person.create :gender => "male", :first_name => "Connor", :middle_initial => "J", :last_name => "Price", :street_address => "75 Round Drive", :city => "Macquarie Hills", :state => "NSW", :postcode => "2285", :email => "Connor.J.Price@dodgit.com", :birthday => "1942/6/21 00:00:00" | ||
| 324 | Person.create :gender => "female", :first_name => "Nicole", :middle_initial => "J", :last_name => "Patterson", :street_address => "43 Webb Road", :city => "Hamilton South", :state => "NSW", :postcode => "2303", :email => "Nicole.J.Patterson@trashymail.com", :birthday => "1980/2/29 00:00:00" | ||
| 325 | Person.create :gender => "female", :first_name => "Sofia", :middle_initial => "M", :last_name => "Parsons", :street_address => "52 Plug Street", :city => "Oakwood", :state => "NSW", :postcode => "2360", :email => "Sofia.M.Parsons@mailinator.com", :birthday => "1985/8/27 00:00:00" | ||
| 326 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "E", :last_name => "Holloway", :street_address => "12 Ulomogo Street", :city => "Newbury Park", :state => "NSW", :postcode => "2830", :email => "Tegan.E.Holloway@dodgit.com", :birthday => "1981/5/26 00:00:00" | ||
| 327 | Person.create :gender => "female", :first_name => "Amelia", :middle_initial => "S", :last_name => "Dawson", :street_address => "88 Timms Drive", :city => "Kentlyn", :state => "NSW", :postcode => "2560", :email => "Amelia.S.Dawson@pookmail.com", :birthday => "1967/4/9 00:00:00" | ||
| 328 | Person.create :gender => "male", :first_name => "Luke", :middle_initial => "M", :last_name => "Martin", :street_address => "59 Mt Berryman Road", :city => "Grantham", :state => "QLD", :postcode => "4347", :email => "Luke.M.Martin@pookmail.com", :birthday => "1956/4/10 00:00:00" | ||
| 329 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "L", :last_name => "Doyle", :street_address => "49 Mackie Street", :city => "Nerrigundah", :state => "NSW", :postcode => "2545", :email => "Jacob.L.Doyle@dodgit.com", :birthday => "1968/3/1 00:00:00" | ||
| 330 | Person.create :gender => "female", :first_name => "Charlotte", :middle_initial => "J", :last_name => "Lee", :street_address => "23 Clifton Street", :city => "Murchison North", :state => "VIC", :postcode => "3610", :email => "Charlotte.J.Lee@pookmail.com", :birthday => "1966/2/26 00:00:00" | ||
| 331 | Person.create :gender => "female", :first_name => "Caitlin", :middle_initial => "J", :last_name => "Whittaker", :street_address => "67 Eurack Court", :city => "Third Creek", :state => "NSW", :postcode => "2583", :email => "Caitlin.J.Whittaker@pookmail.com", :birthday => "1978/5/23 00:00:00" | ||
| 332 | Person.create :gender => "male", :first_name => "Corey", :middle_initial => "G", :last_name => "Houghton", :street_address => "6 Mildura Street", :city => "Gray", :state => "TAS", :postcode => "7215", :email => "Corey.G.Houghton@trashymail.com", :birthday => "1974/12/15 00:00:00" | ||
| 333 | Person.create :gender => "male", :first_name => "Samuel", :middle_initial => "A", :last_name => "Akhtar", :street_address => "59 Bourke Crescent", :city => "Broughton", :state => "VIC", :postcode => "3418", :email => "Samuel.A.Akhtar@dodgit.com", :birthday => "1944/3/11 00:00:00" | ||
| 334 | Person.create :gender => "male", :first_name => "Alex", :middle_initial => "L", :last_name => "Hamilton", :street_address => "46 Derry Street", :city => "Cashmere", :state => "QLD", :postcode => "4500", :email => "Alex.L.Hamilton@trashymail.com", :birthday => "1941/10/21 00:00:00" | ||
| 335 | Person.create :gender => "female", :first_name => "Natasha", :middle_initial => "H", :last_name => "Lees", :street_address => "46 Barker Street", :city => "Coblinine", :state => "WA", :postcode => "6317", :email => "Natasha.H.Lees@pookmail.com", :birthday => "1953/6/2 00:00:00" | ||
| 336 | Person.create :gender => "female", :first_name => "Lauren", :middle_initial => "S", :last_name => "Sharpe", :street_address => "47 Manchester Road", :city => "Berrico", :state => "NSW", :postcode => "2422", :email => "Lauren.S.Sharpe@spambob.com", :birthday => "1985/8/7 00:00:00" | ||
| 337 | Person.create :gender => "male", :first_name => "Mason", :middle_initial => "A", :last_name => "Ellis", :street_address => "14 Halsey Road", :city => "Encounter Bay", :state => "SA", :postcode => "5211", :email => "Mason.A.Ellis@trashymail.com", :birthday => "1952/2/11 00:00:00" | ||
| 338 | Person.create :gender => "female", :first_name => "Elise", :middle_initial => "L", :last_name => "Buckley", :street_address => "97 Redesdale Rd", :city => "Mandurang", :state => "VIC", :postcode => "3551", :email => "Elise.L.Buckley@mailinator.com", :birthday => "1940/6/18 00:00:00" | ||
| 339 | Person.create :gender => "female", :first_name => "Louise", :middle_initial => "A", :last_name => "Garner", :street_address => "41 Stanley Drive", :city => "Mount Julian", :state => "QLD", :postcode => "4800", :email => "Louise.A.Garner@spambob.com", :birthday => "1944/8/25 00:00:00" | ||
| 340 | Person.create :gender => "female", :first_name => "Lara", :middle_initial => "J", :last_name => "White", :street_address => "39 Shamrock Avenue", :city => "Lilli Pilli", :state => "NSW", :postcode => "2536", :email => "Lara.J.White@spambob.com", :birthday => "1968/8/31 00:00:00" | ||
| 341 | Person.create :gender => "male", :first_name => "Dylan", :middle_initial => "C", :last_name => "Goddard", :street_address => "75 Alfred Street", :city => "Widgiemooltha", :state => "WA", :postcode => "6443", :email => "Dylan.C.Goddard@dodgit.com", :birthday => "1960/10/7 00:00:00" | ||
| 342 | Person.create :gender => "male", :first_name => "Harrison", :middle_initial => "J", :last_name => "Bryan", :street_address => "76 Capper Street", :city => "The Limits", :state => "QLD", :postcode => "4625", :email => "Harrison.J.Bryan@spambob.com", :birthday => "1942/12/13 00:00:00" | ||
| 343 | Person.create :gender => "female", :first_name => "Chelsea", :middle_initial => "L", :last_name => "Duffy", :street_address => "35 South Street", :city => "Sandford", :state => "TAS", :postcode => "7020", :email => "Chelsea.L.Duffy@mailinator.com", :birthday => "1961/7/25 00:00:00" | ||
| 344 | Person.create :gender => "male", :first_name => "David", :middle_initial => "G", :last_name => "Noble", :street_address => "91 Nerrigundah Drive", :city => "Pioneer Bay", :state => "VIC", :postcode => "3984", :email => "David.G.Noble@dodgit.com", :birthday => "1971/6/7 00:00:00" | ||
| 345 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "P", :last_name => "Lucas", :street_address => "28 Halsey Road", :city => "Silverton", :state => "SA", :postcode => "5204", :email => "Ava.P.Lucas@pookmail.com", :birthday => "1981/9/2 00:00:00" | ||
| 346 | Person.create :gender => "female", :first_name => "Sofia", :middle_initial => "J", :last_name => "Mann", :street_address => "76 Boulter Close", :city => "Wooroonooran", :state => "QLD", :postcode => "4860", :email => "Sofia.J.Mann@mailinator.com", :birthday => "1952/9/26 00:00:00" | ||
| 347 | Person.create :gender => "male", :first_name => "Nicholas", :middle_initial => "B", :last_name => "Wall", :street_address => "51 South Street", :city => "Ridgeway", :state => "TAS", :postcode => "7054", :email => "Nicholas.B.Wall@spambob.com", :birthday => "1967/11/10 00:00:00" | ||
| 348 | Person.create :gender => "male", :first_name => "Aaron", :middle_initial => "A", :last_name => "Nelson", :street_address => "53 Alfred Street", :city => "Monjingup", :state => "WA", :postcode => "6450", :email => "Aaron.A.Nelson@trashymail.com", :birthday => "1947/6/5 00:00:00" | ||
| 349 | Person.create :gender => "female", :first_name => "Harriet", :middle_initial => "R", :last_name => "Armstrong", :street_address => "70 Frencham Street", :city => "Geehi", :state => "NSW", :postcode => "2642", :email => "Harriet.R.Armstrong@trashymail.com", :birthday => "1947/1/9 00:00:00" | ||
| 350 | Person.create :gender => "female", :first_name => "Aimee", :middle_initial => "S", :last_name => "Hayward", :street_address => "35 Lane Street", :city => "Diamond Creek", :state => "VIC", :postcode => "3089", :email => "Aimee.S.Hayward@spambob.com", :birthday => "1968/11/21 00:00:00" | ||
| 351 | Person.create :gender => "male", :first_name => "Adam", :middle_initial => "S", :last_name => "Watkins", :street_address => "3 Magnolia Drive", :city => "Revesby Heights", :state => "NSW", :postcode => "2212", :email => "Adam.S.Watkins@spambob.com", :birthday => "1942/10/25 00:00:00" | ||
| 352 | Person.create :gender => "female", :first_name => "Ella", :middle_initial => "M", :last_name => "Clarke", :street_address => "92 Frouds Road", :city => "Cobberas", :state => "VIC", :postcode => "3900", :email => "Ella.M.Clarke@pookmail.com", :birthday => "1965/4/12 00:00:00" | ||
| 353 | Person.create :gender => "male", :first_name => "Reece", :middle_initial => "F", :last_name => "Mellor", :street_address => "97 English Street", :city => "Greenbanks", :state => "SA", :postcode => "5253", :email => "Reece.F.Mellor@trashymail.com", :birthday => "1973/9/30 00:00:00" | ||
| 354 | Person.create :gender => "female", :first_name => "Mollie", :middle_initial => "J", :last_name => "Lucas", :street_address => "44 Corio Street", :city => "Barongarook West", :state => "VIC", :postcode => "3249", :email => "Mollie.J.Lucas@trashymail.com", :birthday => "1948/11/28 00:00:00" | ||
| 355 | Person.create :gender => "male", :first_name => "Jordan", :middle_initial => "D", :last_name => "Butcher", :street_address => "7 Kintyre Street", :city => "Rochedale South", :state => "QLD", :postcode => "4123", :email => "Jordan.D.Butcher@spambob.com", :birthday => "1955/6/9 00:00:00" | ||
| 356 | Person.create :gender => "female", :first_name => "Mia", :middle_initial => "R", :last_name => "Alexander", :street_address => "74 Dora Creek", :city => "North Lismore", :state => "NSW", :postcode => "2480", :email => "Mia.R.Alexander@dodgit.com", :birthday => "1984/2/10 00:00:00" | ||
| 357 | Person.create :gender => "male", :first_name => "Reece", :middle_initial => "S", :last_name => "Griffin", :street_address => "34 Bette McNee Street", :city => "Nacurrie", :state => "NSW", :postcode => "2734", :email => "Reece.S.Griffin@dodgit.com", :birthday => "1963/4/1 00:00:00" | ||
| 358 | Person.create :gender => "female", :first_name => "Evie", :middle_initial => "J", :last_name => "Pugh", :street_address => "60 Adavale Road", :city => "Currawang", :state => "NSW", :postcode => "2580", :email => "Evie.J.Pugh@pookmail.com", :birthday => "1978/1/27 00:00:00" | ||
| 359 | Person.create :gender => "female", :first_name => "Paige", :middle_initial => "J", :last_name => "Todd", :street_address => "95 Southwell Crescent", :city => "Elgin", :state => "WA", :postcode => "6237", :email => "Paige.J.Todd@mailinator.com", :birthday => "1976/5/27 00:00:00" | ||
| 360 | Person.create :gender => "female", :first_name => "Katie", :middle_initial => "D", :last_name => "Baxter", :street_address => "70 Friar John Way", :city => "Leda", :state => "WA", :postcode => "6170", :email => "Katie.D.Baxter@pookmail.com", :birthday => "1985/12/18 00:00:00" | ||
| 361 | Person.create :gender => "male", :first_name => "Joe", :middle_initial => "P", :last_name => "Flynn", :street_address => "26 Lapko Road", :city => "Jacup", :state => "WA", :postcode => "6337", :email => "Joe.P.Flynn@dodgit.com", :birthday => "1981/7/28 00:00:00" | ||
| 362 | Person.create :gender => "male", :first_name => "Nathan", :middle_initial => "J", :last_name => "Barton", :street_address => "23 Oriana Street", :city => "Kiar", :state => "NSW", :postcode => "2259", :email => "Nathan.J.Barton@spambob.com", :birthday => "1958/5/26 00:00:00" | ||
| 363 | Person.create :gender => "female", :first_name => "Sienna", :middle_initial => "D", :last_name => "Barker", :street_address => "98 Watson Street", :city => "Roslynmead", :state => "VIC", :postcode => "3564", :email => "Sienna.D.Barker@mailinator.com", :birthday => "1980/1/27 00:00:00" | ||
| 364 | Person.create :gender => "male", :first_name => "Robert", :middle_initial => "E", :last_name => "Dyer", :street_address => "20 Marlin Avenue", :city => "Gunning", :state => "NSW", :postcode => "2581", :email => "Robert.E.Dyer@spambob.com", :birthday => "1971/5/1 00:00:00" | ||
| 365 | Person.create :gender => "female", :first_name => "Alisha", :middle_initial => "F", :last_name => "Lyons", :street_address => "10 Noalimba Avenue", :city => "Arding", :state => "NSW", :postcode => "2358", :email => "Alisha.F.Lyons@spambob.com", :birthday => "1943/2/25 00:00:00" | ||
| 366 | Person.create :gender => "female", :first_name => "Lucy", :middle_initial => "C", :last_name => "Norman", :street_address => "47 Pelican Road", :city => "Hobart", :state => "TAS", :postcode => "7001", :email => "Lucy.C.Norman@mailinator.com", :birthday => "1942/5/24 00:00:00" | ||
| 367 | Person.create :gender => "female", :first_name => "Lilly", :middle_initial => "M", :last_name => "Freeman", :street_address => "96 Ugoa Street", :city => "Mount George", :state => "NSW", :postcode => "2424", :email => "Lilly.M.Freeman@pookmail.com", :birthday => "1978/5/18 00:00:00" | ||
| 368 | Person.create :gender => "male", :first_name => "Riley", :middle_initial => "C", :last_name => "Henderson", :street_address => "55 Prince Street", :city => "Kungala", :state => "NSW", :postcode => "2460", :email => "Riley.C.Henderson@mailinator.com", :birthday => "1977/7/27 00:00:00" | ||
| 369 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "L", :last_name => "Lane", :street_address => "3 Masthead Drive", :city => "Kawana", :state => "QLD", :postcode => "4701", :email => "Maddison.L.Lane@trashymail.com", :birthday => "1983/3/31 00:00:00" | ||
| 370 | Person.create :gender => "female", :first_name => "Alexandra", :middle_initial => "L", :last_name => "Chadwick", :street_address => "33 Ocean Pde", :city => "Buchanan", :state => "QLD", :postcode => "4816", :email => "Alexandra.L.Chadwick@mailinator.com", :birthday => "1957/1/31 00:00:00" | ||
| 371 | Person.create :gender => "male", :first_name => "Harvey", :middle_initial => "P", :last_name => "Russell", :street_address => "91 Villeneuve Street", :city => "Smoko", :state => "VIC", :postcode => "3741", :email => "Harvey.P.Russell@trashymail.com", :birthday => "1954/2/3 00:00:00" | ||
| 372 | Person.create :gender => "female", :first_name => "Courtney", :middle_initial => "Z", :last_name => "Jenkins", :street_address => "54 Dora Creek", :city => "Mountain Top", :state => "NSW", :postcode => "2480", :email => "Courtney.Z.Jenkins@trashymail.com", :birthday => "1957/10/30 00:00:00" | ||
| 373 | Person.create :gender => "female", :first_name => "Niamh", :middle_initial => "O", :last_name => "Armstrong", :street_address => "95 Cambridge Street", :city => "Emu Plains", :state => "NSW", :postcode => "2750", :email => "Niamh.O.Armstrong@dodgit.com", :birthday => "1985/10/30 00:00:00" | ||
| 374 | Person.create :gender => "male", :first_name => "Toby", :middle_initial => "C", :last_name => "Sutton", :street_address => "53 Bass Street", :city => "Booyong", :state => "NSW", :postcode => "2480", :email => "Toby.C.Sutton@mailinator.com", :birthday => "1941/8/13 00:00:00" | ||
| 375 | Person.create :gender => "male", :first_name => "Taylor", :middle_initial => "K", :last_name => "Lowe", :street_address => "74 Raglan Street", :city => "Ballogie", :state => "QLD", :postcode => "4610", :email => "Taylor.K.Lowe@mailinator.com", :birthday => "1975/3/24 00:00:00" | ||
| 376 | Person.create :gender => "male", :first_name => "Bradley", :middle_initial => "R", :last_name => "Cook", :street_address => "95 Peterho Boulevard", :city => "Hillier", :state => "SA", :postcode => "5116", :email => "Bradley.R.Cook@dodgit.com", :birthday => "1962/2/26 00:00:00" | ||
| 377 | Person.create :gender => "female", :first_name => "Danielle", :middle_initial => "L", :last_name => "Graham", :street_address => "25 Maintongoon Road", :city => "Walhalla", :state => "VIC", :postcode => "3825", :email => "Danielle.L.Graham@pookmail.com", :birthday => "1948/10/6 00:00:00" | ||
| 378 | Person.create :gender => "female", :first_name => "Louise", :middle_initial => "L", :last_name => "Collier", :street_address => "37 Thule Drive", :city => "Bethel", :state => "SA", :postcode => "5373", :email => "Louise.L.Collier@mailinator.com", :birthday => "1947/2/12 00:00:00" | ||
| 379 | Person.create :gender => "male", :first_name => "Dylan", :middle_initial => "G", :last_name => "Grant", :street_address => "11 Arthur Street", :city => "Burroway", :state => "NSW", :postcode => "2821", :email => "Dylan.G.Grant@dodgit.com", :birthday => "1954/11/14 00:00:00" | ||
| 380 | Person.create :gender => "male", :first_name => "Elliot", :middle_initial => "M", :last_name => "Evans", :street_address => "39 Bresnahans Lane", :city => "Paddys River", :state => "NSW", :postcode => "2577", :email => "Elliot.M.Evans@spambob.com", :birthday => "1981/10/1 00:00:00" | ||
| 381 | Person.create :gender => "female", :first_name => "Kate", :middle_initial => "T", :last_name => "Phillips", :street_address => "93 Taltarni Road", :city => "Tottington", :state => "VIC", :postcode => "3478", :email => "Kate.T.Phillips@trashymail.com", :birthday => "1947/5/4 00:00:00" | ||
| 382 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "N", :last_name => "Simmons", :street_address => "80 Derry Street", :city => "Brendale Dc", :state => "QLD", :postcode => "4500", :email => "Isabelle.N.Simmons@dodgit.com", :birthday => "1963/4/14 00:00:00" | ||
| 383 | Person.create :gender => "male", :first_name => "Tyler", :middle_initial => "M", :last_name => "Green", :street_address => "61 Kintyre Street", :city => "Lyons", :state => "QLD", :postcode => "4124", :email => "Tyler.M.Green@trashymail.com", :birthday => "1947/12/11 00:00:00" | ||
| 384 | Person.create :gender => "male", :first_name => "Kian", :middle_initial => "S", :last_name => "Parry", :street_address => "44 Mt Berryman Road", :city => "Crows Nest", :state => "QLD", :postcode => "4355", :email => "Kian.S.Parry@mailinator.com", :birthday => "1952/6/15 00:00:00" | ||
| 385 | Person.create :gender => "male", :first_name => "Henry", :middle_initial => "D", :last_name => "Daly", :street_address => "11 Grandis Road", :city => "Temagog", :state => "NSW", :postcode => "2440", :email => "Henry.D.Daly@trashymail.com", :birthday => "1972/11/22 00:00:00" | ||
| 386 | Person.create :gender => "male", :first_name => "Riley", :middle_initial => "K", :last_name => "Gallagher", :street_address => "36 Ghost Hill Road", :city => "Vineyard", :state => "NSW", :postcode => "2765", :email => "Riley.K.Gallagher@dodgit.com", :birthday => "1940/6/10 00:00:00" | ||
| 387 | Person.create :gender => "male", :first_name => "Finley", :middle_initial => "L", :last_name => "Collins", :street_address => "8 Walpole Avenue", :city => "Paaratte", :state => "VIC", :postcode => "3268", :email => "Finley.L.Collins@dodgit.com", :birthday => "1975/7/17 00:00:00" | ||
| 388 | Person.create :gender => "female", :first_name => "Yasmin", :middle_initial => "M", :last_name => "Fraser", :street_address => "19 Forrest Road", :city => "Cobbora", :state => "NSW", :postcode => "2844", :email => "Yasmin.M.Fraser@spambob.com", :birthday => "1948/3/6 00:00:00" | ||
| 389 | Person.create :gender => "male", :first_name => "Kian", :middle_initial => "J", :last_name => "Wilson", :street_address => "29 Queen Street", :city => "Bayview", :state => "NSW", :postcode => "2104", :email => "Kian.J.Wilson@pookmail.com", :birthday => "1967/8/11 00:00:00" | ||
| 390 | Person.create :gender => "female", :first_name => "Hannah", :middle_initial => "L", :last_name => "Bird", :street_address => "34 Hill Street", :city => "Tiberias", :state => "TAS", :postcode => "7120", :email => "Hannah.L.Bird@trashymail.com", :birthday => "1967/1/7 00:00:00" | ||
| 391 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "L", :last_name => "Hope", :street_address => "13 Hodgson St", :city => "Womina", :state => "QLD", :postcode => "4370", :email => "Francesca.L.Hope@trashymail.com", :birthday => "1984/12/20 00:00:00" | ||
| 392 | Person.create :gender => "female", :first_name => "Natasha", :middle_initial => "L", :last_name => "Blake", :street_address => "60 Masthead Drive", :city => "Limestone Creek", :state => "QLD", :postcode => "4701", :email => "Natasha.L.Blake@dodgit.com", :birthday => "1960/2/3 00:00:00" | ||
| 393 | Person.create :gender => "male", :first_name => "Evan", :middle_initial => "D", :last_name => "Warren", :street_address => "57 Ferny Avenue", :city => "Givelda", :state => "QLD", :postcode => "4670", :email => "Evan.D.Warren@pookmail.com", :birthday => "1943/7/17 00:00:00" | ||
| 394 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "T", :last_name => "Stevenson", :street_address => "84 Wynyard Street", :city => "Gilmore", :state => "NSW", :postcode => "2720", :email => "Francesca.T.Stevenson@spambob.com", :birthday => "1981/8/10 00:00:00" | ||
| 395 | Person.create :gender => "female", :first_name => "Scarlett", :middle_initial => "M", :last_name => "Parkin", :street_address => "58 Lane Street", :city => "Kew", :state => "VIC", :postcode => "3101", :email => "Scarlett.M.Parkin@mailinator.com", :birthday => "1954/2/20 00:00:00" | ||
| 396 | Person.create :gender => "female", :first_name => "Kayleigh", :middle_initial => "S", :last_name => "Moss", :street_address => "87 Atkinson Way", :city => "Mount Anketell", :state => "WA", :postcode => "6714", :email => "Kayleigh.S.Moss@pookmail.com", :birthday => "1963/8/29 00:00:00" | ||
| 397 | Person.create :gender => "male", :first_name => "Evan", :middle_initial => "V", :last_name => "Mellor", :street_address => "75 George Street", :city => "Eromanga", :state => "QLD", :postcode => "4480", :email => "Evan.V.Mellor@pookmail.com", :birthday => "1948/10/1 00:00:00" | ||
| 398 | Person.create :gender => "female", :first_name => "Tilly", :middle_initial => "L", :last_name => "Waters", :street_address => "47 Fernleigh Ave", :city => "Ponto", :state => "NSW", :postcode => "2831", :email => "Tilly.L.Waters@mailinator.com", :birthday => "1976/5/31 00:00:00" | ||
| 399 | Person.create :gender => "male", :first_name => "Billy", :middle_initial => "G", :last_name => "Woods", :street_address => "16 Redesdale Rd", :city => "Toolleen", :state => "VIC", :postcode => "3551", :email => "Billy.G.Woods@dodgit.com", :birthday => "1942/3/17 00:00:00" | ||
| 400 | Person.create :gender => "male", :first_name => "Aaron", :middle_initial => "E", :last_name => "Newman", :street_address => "84 Rupara Street", :city => "Nailsworth", :state => "SA", :postcode => "5083", :email => "Aaron.E.Newman@spambob.com", :birthday => "1983/5/20 00:00:00" | ||
| 401 | Person.create :gender => "female", :first_name => "Jade", :middle_initial => "D", :last_name => "Randall", :street_address => "8 Learmouth Street", :city => "Yatchaw", :state => "VIC", :postcode => "3301", :email => "Jade.D.Randall@pookmail.com", :birthday => "1947/6/7 00:00:00" | ||
| 402 | Person.create :gender => "male", :first_name => "Robert", :middle_initial => "A", :last_name => "Cunningham", :street_address => "57 Shell Road", :city => "Hordern Vale", :state => "VIC", :postcode => "3238", :email => "Robert.A.Cunningham@mailinator.com", :birthday => "1956/9/10 00:00:00" | ||
| 403 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "A", :last_name => "Simmons", :street_address => "72 Endeavour Drive", :city => "Tooligie", :state => "SA", :postcode => "5607", :email => "Isabelle.A.Simmons@trashymail.com", :birthday => "1955/11/15 00:00:00" | ||
| 404 | Person.create :gender => "male", :first_name => "Jack", :middle_initial => "T", :last_name => "Wade", :street_address => "66 Walter Crescent", :city => "Broughton", :state => "NSW", :postcode => "2535", :email => "Jack.T.Wade@trashymail.com", :birthday => "1956/10/10 00:00:00" | ||
| 405 | Person.create :gender => "female", :first_name => "Lucy", :middle_initial => "E", :last_name => "Ali", :street_address => "59 Seaview Court", :city => "Victoria Plains", :state => "QLD", :postcode => "4751", :email => "Lucy.E.Ali@spambob.com", :birthday => "1954/10/29 00:00:00" | ||
| 406 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "R", :last_name => "O'onnor", :street_address => "5 Wharf St", :city => "Holgate", :state => "NSW", :postcode => "2250", :email => "Zachary.R.O'onnor@trashymail.com", :birthday => "1969/7/26 00:00:00" | ||
| 407 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "K", :last_name => "Lucas", :street_address => "71 Gregory Way", :city => "Mandurah North", :state => "WA", :postcode => "6210", :email => "Zachary.K.Lucas@trashymail.com", :birthday => "1963/3/26 00:00:00" | ||
| 408 | Person.create :gender => "female", :first_name => "Phoebe", :middle_initial => "O", :last_name => "Duncan", :street_address => "2 Berambing Crescent", :city => "Doonside", :state => "NSW", :postcode => "2767", :email => "Phoebe.O.Duncan@spambob.com", :birthday => "1950/4/15 00:00:00" | ||
| 409 | Person.create :gender => "female", :first_name => "Molly", :middle_initial => "G", :last_name => "Marsden", :street_address => "19 Panorama Road", :city => "Weabonga", :state => "NSW", :postcode => "2340", :email => "Molly.G.Marsden@mailinator.com", :birthday => "1940/8/30 00:00:00" | ||
| 410 | Person.create :gender => "male", :first_name => "Scott", :middle_initial => "L", :last_name => "Banks", :street_address => "27 Dalgarno Street", :city => "Jews Lagoon", :state => "NSW", :postcode => "2388", :email => "Scott.L.Banks@pookmail.com", :birthday => "1982/9/14 00:00:00" | ||
| 411 | Person.create :gender => "female", :first_name => "Courtney", :middle_initial => "K", :last_name => "Cooper", :street_address => "61 Railway Street", :city => "Greenmount East", :state => "QLD", :postcode => "4359", :email => "Courtney.K.Cooper@pookmail.com", :birthday => "1949/7/29 00:00:00" | ||
| 412 | Person.create :gender => "male", :first_name => "Michael", :middle_initial => "R", :last_name => "Marsden", :street_address => "46 Glenpark Road", :city => "Tucabia", :state => "NSW", :postcode => "2462", :email => "Michael.R.Marsden@trashymail.com", :birthday => "1972/8/25 00:00:00" | ||
| 413 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "R", :last_name => "Howe", :street_address => "45 Pipeclay Road", :city => "Wauchope", :state => "NSW", :postcode => "2446", :email => "Owen.R.Howe@dodgit.com", :birthday => "1964/6/26 00:00:00" | ||
| 414 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "J", :last_name => "Moran", :street_address => "7 Masthead Drive", :city => "Bororen", :state => "QLD", :postcode => "4678", :email => "Francesca.J.Moran@spambob.com", :birthday => "1960/2/17 00:00:00" | ||
| 415 | Person.create :gender => "female", :first_name => "Courtney", :middle_initial => "E", :last_name => "Phillips", :street_address => "33 Atkinson Way", :city => "Bilingurr", :state => "WA", :postcode => "6725", :email => "Courtney.E.Phillips@trashymail.com", :birthday => "1951/6/18 00:00:00" | ||
| 416 | Person.create :gender => "female", :first_name => "Paige", :middle_initial => "O", :last_name => "Nash", :street_address => "73 Hillsdale Road", :city => "Teebar", :state => "QLD", :postcode => "4620", :email => "Paige.O.Nash@spambob.com", :birthday => "1984/3/3 00:00:00" | ||
| 417 | Person.create :gender => "female", :first_name => "Georgia", :middle_initial => "T", :last_name => "Charlton", :street_address => "14 Quayside Vista", :city => "Tomerong", :state => "NSW", :postcode => "2540", :email => "Georgia.T.Charlton@spambob.com", :birthday => "1978/6/28 00:00:00" | ||
| 418 | Person.create :gender => "male", :first_name => "Rhys", :middle_initial => "N", :last_name => "Rees", :street_address => "50 South Street", :city => "Glaziers Bay", :state => "TAS", :postcode => "7109", :email => "Rhys.N.Rees@spambob.com", :birthday => "1941/8/6 00:00:00" | ||
| 419 | Person.create :gender => "male", :first_name => "Jack", :middle_initial => "L", :last_name => "Bryant", :street_address => "3 Edgewater Close", :city => "Cambewarra", :state => "NSW", :postcode => "2540", :email => "Jack.L.Bryant@trashymail.com", :birthday => "1957/3/28 00:00:00" | ||
| 420 | Person.create :gender => "male", :first_name => "Isaac", :middle_initial => "J", :last_name => "Hughes", :street_address => "62 Bowden Street", :city => "La Perouse", :state => "NSW", :postcode => "2036", :email => "Isaac.J.Hughes@pookmail.com", :birthday => "1967/9/23 00:00:00" | ||
| 421 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "P", :last_name => "Schofield", :street_address => "19 Spencer Street", :city => "Goomeribong", :state => "QLD", :postcode => "4601", :email => "Ava.P.Schofield@spambob.com", :birthday => "1968/7/30 00:00:00" | ||
| 422 | Person.create :gender => "female", :first_name => "Chloe", :middle_initial => "H", :last_name => "Wilkinson", :street_address => "20 Treasure Island Avenue", :city => "Sarabah", :state => "QLD", :postcode => "4275", :email => "Chloe.H.Wilkinson@pookmail.com", :birthday => "1967/2/3 00:00:00" | ||
| 423 | Person.create :gender => "female", :first_name => "Samantha", :middle_initial => "E", :last_name => "Berry", :street_address => "31 Woodwark Crescent", :city => "Badu Island", :state => "QLD", :postcode => "4875", :email => "Samantha.E.Berry@dodgit.com", :birthday => "1973/2/18 00:00:00" | ||
| 424 | Person.create :gender => "female", :first_name => "Cerys", :middle_initial => "L", :last_name => "Ferguson", :street_address => "49 Bathurst Road", :city => "Wiagdon", :state => "NSW", :postcode => "2795", :email => "Cerys.L.Ferguson@pookmail.com", :birthday => "1958/7/24 00:00:00" | ||
| 425 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "G", :last_name => "Sharpe", :street_address => "96 Ocean Street", :city => "Wollogorang Station", :state => "NT", :postcode => "0862", :email => "Isabelle.G.Sharpe@spambob.com", :birthday => "1983/9/15 00:00:00" | ||
| 426 | Person.create :gender => "female", :first_name => "Rachel", :middle_initial => "M", :last_name => "Wells", :street_address => "14 Ronald Crescent", :city => "Boyne Island", :state => "QLD", :postcode => "4680", :email => "Rachel.M.Wells@trashymail.com", :birthday => "1968/5/29 00:00:00" | ||
| 427 | Person.create :gender => "male", :first_name => "Dylan", :middle_initial => "C", :last_name => "Parkinson", :street_address => "12 Davis Street", :city => "Kelvin Grove Dc", :state => "QLD", :postcode => "4059", :email => "Dylan.C.Parkinson@trashymail.com", :birthday => "1966/10/21 00:00:00" | ||
| 428 | Person.create :gender => "female", :first_name => "Matilda", :middle_initial => "B", :last_name => "Parsons", :street_address => "74 Commercial Street", :city => "Woodend North", :state => "VIC", :postcode => "3442", :email => "Matilda.B.Parsons@trashymail.com", :birthday => "1942/8/2 00:00:00" | ||
| 429 | Person.create :gender => "female", :first_name => "Scarlett", :middle_initial => "M", :last_name => "May", :street_address => "74 Wigley Street", :city => "Bedford Park", :state => "SA", :postcode => "5042", :email => "Scarlett.M.May@spambob.com", :birthday => "1977/10/12 00:00:00" | ||
| 430 | Person.create :gender => "male", :first_name => "Aidan", :middle_initial => "A", :last_name => "Chamberlain", :street_address => "51 Roseda-Tinamba Road", :city => "Turtons Creek", :state => "VIC", :postcode => "3960", :email => "Aidan.A.Chamberlain@trashymail.com", :birthday => "1955/4/9 00:00:00" | ||
| 431 | Person.create :gender => "female", :first_name => "Ellie", :middle_initial => "J", :last_name => "Greenwood", :street_address => "37 Webb Road", :city => "Hillsborough", :state => "NSW", :postcode => "2290", :email => "Ellie.J.Greenwood@trashymail.com", :birthday => "1970/12/17 00:00:00" | ||
| 432 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "Z", :last_name => "McDonald", :street_address => "73 Kooljak Rd", :city => "Sabina River", :state => "WA", :postcode => "6280", :email => "Christopher.Z.McDonald@trashymail.com", :birthday => "1961/6/15 00:00:00" | ||
| 433 | Person.create :gender => "female", :first_name => "Amber", :middle_initial => "T", :last_name => "Arnold", :street_address => "28 Grandis Road", :city => "Lower Creek", :state => "NSW", :postcode => "2440", :email => "Amber.T.Arnold@dodgit.com", :birthday => "1961/3/1 00:00:00" | ||
| 434 | Person.create :gender => "male", :first_name => "Josh", :middle_initial => "N", :last_name => "Hardy", :street_address => "74 Thone Street", :city => "Killawarra", :state => "NSW", :postcode => "2429", :email => "Josh.N.Hardy@spambob.com", :birthday => "1944/9/13 00:00:00" | ||
| 435 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "M", :last_name => "Pollard", :street_address => "44 Adavale Road", :city => "Six Mile Flat", :state => "NSW", :postcode => "2580", :email => "Maddison.M.Pollard@spambob.com", :birthday => "1945/6/27 00:00:00" | ||
| 436 | Person.create :gender => "female", :first_name => "Holly", :middle_initial => "J", :last_name => "Hughes", :street_address => "93 Yangan Drive", :city => "Chilcotts Creek", :state => "NSW", :postcode => "2339", :email => "Holly.J.Hughes@trashymail.com", :birthday => "1951/8/6 00:00:00" | ||
| 437 | Person.create :gender => "male", :first_name => "Bailey", :middle_initial => "N", :last_name => "Martin", :street_address => "87 Moruya Road", :city => "Farringdon", :state => "NSW", :postcode => "2622", :email => "Bailey.N.Martin@trashymail.com", :birthday => "1980/7/3 00:00:00" | ||
| 438 | Person.create :gender => "male", :first_name => "Ryan", :middle_initial => "R", :last_name => "O'ullivan", :street_address => "55 Taylor Street", :city => "Waaia", :state => "VIC", :postcode => "3637", :email => "Ryan.R.O'ullivan@spambob.com", :birthday => "1981/4/26 00:00:00" | ||
| 439 | Person.create :gender => "female", :first_name => "Georgia", :middle_initial => "B", :last_name => "Gough", :street_address => "29 Bungana Drive", :city => "Brinkworth", :state => "SA", :postcode => "5464", :email => "Georgia.B.Gough@pookmail.com", :birthday => "1984/2/7 00:00:00" | ||
| 440 | Person.create :gender => "male", :first_name => "Edward", :middle_initial => "N", :last_name => "Harper", :street_address => "38 Taylor Street", :city => "Katandra", :state => "VIC", :postcode => "3634", :email => "Edward.N.Harper@trashymail.com", :birthday => "1980/7/31 00:00:00" | ||
| 441 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "A", :last_name => "Cross", :street_address => "11 Rimbanda Road", :city => "Tungsten", :state => "NSW", :postcode => "2371", :email => "Christopher.A.Cross@spambob.com", :birthday => "1963/12/13 00:00:00" | ||
| 442 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "P", :last_name => "Archer", :street_address => "15 Spencer Street", :city => "Yaroomba", :state => "QLD", :postcode => "4573", :email => "Ethan.P.Archer@spambob.com", :birthday => "1963/10/12 00:00:00" | ||
| 443 | Person.create :gender => "female", :first_name => "Sarah", :middle_initial => "B", :last_name => "Dean", :street_address => "86 Bellion Drive", :city => "Jalbarragup", :state => "WA", :postcode => "6275", :email => "Sarah.B.Dean@mailinator.com", :birthday => "1948/4/29 00:00:00" | ||
| 444 | Person.create :gender => "male", :first_name => "Henry", :middle_initial => "T", :last_name => "Randall", :street_address => "22 Amiens Road", :city => "Long Creek", :state => "NSW", :postcode => "2850", :email => "Henry.T.Randall@dodgit.com", :birthday => "1946/8/10 00:00:00" | ||
| 445 | Person.create :gender => "male", :first_name => "Rhys", :middle_initial => "C", :last_name => "Pearson", :street_address => "30 Paradise Falls Road", :city => "Bowser", :state => "VIC", :postcode => "3678", :email => "Rhys.C.Pearson@spambob.com", :birthday => "1973/5/12 00:00:00" | ||
| 446 | Person.create :gender => "female", :first_name => "Natasha", :middle_initial => "C", :last_name => "Kennedy", :street_address => "79 McKillop Street", :city => "Berrambool", :state => "VIC", :postcode => "3379", :email => "Natasha.C.Kennedy@trashymail.com", :birthday => "1953/6/19 00:00:00" | ||
| 447 | Person.create :gender => "female", :first_name => "Lily", :middle_initial => "D", :last_name => "Gray", :street_address => "75 Shaw Drive", :city => "Eddington", :state => "VIC", :postcode => "3472", :email => "Lily.D.Gray@dodgit.com", :birthday => "1968/3/1 00:00:00" | ||
| 448 | Person.create :gender => "female", :first_name => "Ella", :middle_initial => "H", :last_name => "Woodward", :street_address => "1 Sullivan Court", :city => "Boolite", :state => "VIC", :postcode => "3480", :email => "Ella.H.Woodward@mailinator.com", :birthday => "1979/10/19 00:00:00" | ||
| 449 | Person.create :gender => "male", :first_name => "Andrew", :middle_initial => "E", :last_name => "Sanderson", :street_address => "59 Myrtle Street", :city => "Yarrawonga", :state => "VIC", :postcode => "3730", :email => "Andrew.E.Sanderson@mailinator.com", :birthday => "1954/12/13 00:00:00" | ||
| 450 | Person.create :gender => "female", :first_name => "Niamh", :middle_initial => "T", :last_name => "Gordon", :street_address => "54 Eshelby Drive", :city => "Rangewood", :state => "QLD", :postcode => "4817", :email => "Niamh.T.Gordon@pookmail.com", :birthday => "1977/4/17 00:00:00" | ||
| 451 | Person.create :gender => "female", :first_name => "Lola", :middle_initial => "O", :last_name => "Cole", :street_address => "93 Armstrong Street", :city => "Mincha", :state => "VIC", :postcode => "3575", :email => "Lola.O.Cole@pookmail.com", :birthday => "1985/5/10 00:00:00" | ||
| 452 | Person.create :gender => "female", :first_name => "Kayleigh", :middle_initial => "A", :last_name => "Kaur", :street_address => "97 Bayview Close", :city => "Orange Creek", :state => "QLD", :postcode => "4715", :email => "Kayleigh.A.Kaur@trashymail.com", :birthday => "1953/3/9 00:00:00" | ||
| 453 | Person.create :gender => "male", :first_name => "Ewan", :middle_initial => "M", :last_name => "Bradley", :street_address => "56 Butler Crescent", :city => "Sweetmans Creek", :state => "NSW", :postcode => "2325", :email => "Ewan.M.Bradley@spambob.com", :birthday => "1966/4/13 00:00:00" | ||
| 454 | Person.create :gender => "female", :first_name => "Daisy", :middle_initial => "S", :last_name => "Peters", :street_address => "6 Cassinia Street", :city => "Darbalara", :state => "NSW", :postcode => "2722", :email => "Daisy.S.Peters@spambob.com", :birthday => "1969/6/27 00:00:00" | ||
| 455 | Person.create :gender => "male", :first_name => "Jordan", :middle_initial => "B", :last_name => "Stephens", :street_address => "63 Shaw Drive", :city => "Elmhurst", :state => "VIC", :postcode => "3469", :email => "Jordan.B.Stephens@trashymail.com", :birthday => "1977/8/9 00:00:00" | ||
| 456 | Person.create :gender => "female", :first_name => "Charlie", :middle_initial => "E", :last_name => "Davey", :street_address => "27 Creek Street", :city => "Southwood", :state => "QLD", :postcode => "4406", :email => "Charlie.E.Davey@trashymail.com", :birthday => "1981/11/13 00:00:00" | ||
| 457 | Person.create :gender => "male", :first_name => "Robert", :middle_initial => "D", :last_name => "Fraser", :street_address => "46 Myrtle Street", :city => "Yarrawonga South", :state => "VIC", :postcode => "3730", :email => "Robert.D.Fraser@mailinator.com", :birthday => "1948/12/23 00:00:00" | ||
| 458 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "M", :last_name => "Willis", :street_address => "14 Faulkner Street", :city => "Thalgarrah", :state => "NSW", :postcode => "2350", :email => "Jake.M.Willis@spambob.com", :birthday => "1964/3/24 00:00:00" | ||
| 459 | Person.create :gender => "male", :first_name => "Oliver", :middle_initial => "E", :last_name => "Middleton", :street_address => "64 Meyer Road", :city => "Krondorf", :state => "SA", :postcode => "5352", :email => "Oliver.E.Middleton@spambob.com", :birthday => "1951/11/21 00:00:00" | ||
| 460 | Person.create :gender => "female", :first_name => "Katie", :middle_initial => "H", :last_name => "Archer", :street_address => "20 Gregory Way", :city => "Wagerup", :state => "WA", :postcode => "6215", :email => "Katie.H.Archer@mailinator.com", :birthday => "1971/5/9 00:00:00" | ||
| 461 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "G", :last_name => "Nicholls", :street_address => "54 Healy Road", :city => "Wilga West", :state => "WA", :postcode => "6243", :email => "Jacob.G.Nicholls@pookmail.com", :birthday => "1965/9/17 00:00:00" | ||
| 462 | Person.create :gender => "male", :first_name => "Harrison", :middle_initial => "K", :last_name => "Russell", :street_address => "12 Banksia Street", :city => "Nunile", :state => "WA", :postcode => "6566", :email => "Harrison.K.Russell@trashymail.com", :birthday => "1961/8/6 00:00:00" | ||
| 463 | Person.create :gender => "female", :first_name => "Poppy", :middle_initial => "C", :last_name => "Miller", :street_address => "87 Jacolite Street", :city => "Wangara Dc", :state => "WA", :postcode => "6065", :email => "Poppy.C.Miller@trashymail.com", :birthday => "1975/6/22 00:00:00" | ||
| 464 | Person.create :gender => "female", :first_name => "Mollie", :middle_initial => "M", :last_name => "Stewart", :street_address => "69 Henry Moss Court", :city => "Germein Bay", :state => "SA", :postcode => "5495", :email => "Mollie.M.Stewart@trashymail.com", :birthday => "1968/6/19 00:00:00" | ||
| 465 | Person.create :gender => "male", :first_name => "Kian", :middle_initial => "M", :last_name => "Barker", :street_address => "75 Girvan Grove", :city => "Robinvale", :state => "VIC", :postcode => "3549", :email => "Kian.M.Barker@pookmail.com", :birthday => "1980/3/25 00:00:00" | ||
| 466 | Person.create :gender => "female", :first_name => "Skye", :middle_initial => "G", :last_name => "Hart", :street_address => "17 Banksia Street", :city => "Wooroloo", :state => "WA", :postcode => "6558", :email => "Skye.G.Hart@mailinator.com", :birthday => "1974/10/19 00:00:00" | ||
| 467 | Person.create :gender => "male", :first_name => "Charles", :middle_initial => "R", :last_name => "Kemp", :street_address => "54 Seiferts Rd", :city => "Byfield", :state => "QLD", :postcode => "4703", :email => "Charles.R.Kemp@mailinator.com", :birthday => "1943/10/28 00:00:00" | ||
| 468 | Person.create :gender => "female", :first_name => "Evie", :middle_initial => "H", :last_name => "Atkinson", :street_address => "72 Peninsula Drive", :city => "Engadine", :state => "NSW", :postcode => "2233", :email => "Evie.H.Atkinson@trashymail.com", :birthday => "1975/8/27 00:00:00" | ||
| 469 | Person.create :gender => "female", :first_name => "Hollie", :middle_initial => "S", :last_name => "John", :street_address => "60 Seaview Court", :city => "Sarina", :state => "QLD", :postcode => "4737", :email => "Hollie.S.John@dodgit.com", :birthday => "1979/6/2 00:00:00" | ||
| 470 | Person.create :gender => "male", :first_name => "Nathan", :middle_initial => "B", :last_name => "Kemp", :street_address => "21 Jones Road", :city => "Wacol", :state => "QLD", :postcode => "4076", :email => "Nathan.B.Kemp@dodgit.com", :birthday => "1940/9/30 00:00:00" | ||
| 471 | Person.create :gender => "female", :first_name => "Demi", :middle_initial => "J", :last_name => "Whitehead", :street_address => "35 Wallis Street", :city => "Randwick", :state => "NSW", :postcode => "2031", :email => "Demi.J.Whitehead@mailinator.com", :birthday => "1962/11/11 00:00:00" | ||
| 472 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "L", :last_name => "Knight", :street_address => "28 Cubbine Road", :city => "Turkey Hill", :state => "WA", :postcode => "6426", :email => "Jacob.L.Knight@mailinator.com", :birthday => "1959/10/29 00:00:00" | ||
| 473 | Person.create :gender => "female", :first_name => "Maisie", :middle_initial => "J", :last_name => "Pritchard", :street_address => "7 Nerrigundah Drive", :city => "Cardinia", :state => "VIC", :postcode => "3978", :email => "Maisie.J.Pritchard@mailinator.com", :birthday => "1970/9/15 00:00:00" | ||
| 474 | Person.create :gender => "female", :first_name => "Rosie", :middle_initial => "K", :last_name => "Adams", :street_address => "72 Webb Road", :city => "New Lambton Heights", :state => "NSW", :postcode => "2305", :email => "Rosie.K.Adams@pookmail.com", :birthday => "1948/8/13 00:00:00" | ||
| 475 | Person.create :gender => "female", :first_name => "Nicole", :middle_initial => "S", :last_name => "Shaw", :street_address => "4 High Street", :city => "Warooka", :state => "SA", :postcode => "5577", :email => "Nicole.S.Shaw@trashymail.com", :birthday => "1983/12/20 00:00:00" | ||
| 476 | Person.create :gender => "female", :first_name => "Matilda", :middle_initial => "N", :last_name => "Gardiner", :street_address => "12 Church Street", :city => "Bordertown", :state => "SA", :postcode => "5268", :email => "Matilda.N.Gardiner@mailinator.com", :birthday => "1968/11/14 00:00:00" | ||
| 477 | Person.create :gender => "male", :first_name => "George", :middle_initial => "N", :last_name => "Patterson", :street_address => "86 Hill Street", :city => "Oyster Cove", :state => "TAS", :postcode => "7150", :email => "George.N.Patterson@mailinator.com", :birthday => "1956/9/7 00:00:00" | ||
| 478 | Person.create :gender => "female", :first_name => "Isobel", :middle_initial => "J", :last_name => "West", :street_address => "85 Quoin Road", :city => "Rushy Lagoon", :state => "TAS", :postcode => "7264", :email => "Isobel.J.West@dodgit.com", :birthday => "1968/7/29 00:00:00" | ||
| 479 | Person.create :gender => "female", :first_name => "Freya", :middle_initial => "B", :last_name => "Gregory", :street_address => "16 Gregory Way", :city => "Coolup", :state => "WA", :postcode => "6214", :email => "Freya.B.Gregory@pookmail.com", :birthday => "1974/7/26 00:00:00" | ||
| 480 | Person.create :gender => "female", :first_name => "Madeleine", :middle_initial => "J", :last_name => "Chandler", :street_address => "75 Clifton Street", :city => "Narrung", :state => "VIC", :postcode => "3597", :email => "Madeleine.J.Chandler@dodgit.com", :birthday => "1940/1/4 00:00:00" | ||
| 481 | Person.create :gender => "female", :first_name => "Nicole", :middle_initial => "B", :last_name => "Reynolds", :street_address => "34 Point Walter Road", :city => "South Lake", :state => "WA", :postcode => "6164", :email => "Nicole.B.Reynolds@pookmail.com", :birthday => "1969/3/22 00:00:00" | ||
| 482 | Person.create :gender => "male", :first_name => "Jude", :middle_initial => "I", :last_name => "Baldwin", :street_address => "63 George Street", :city => "Cooladdi", :state => "QLD", :postcode => "4479", :email => "Jude.I.Baldwin@mailinator.com", :birthday => "1964/8/5 00:00:00" | ||
| 483 | Person.create :gender => "female", :first_name => "Lilly", :middle_initial => "B", :last_name => "Brady", :street_address => "38 Lapko Road", :city => "Magitup", :state => "WA", :postcode => "6338", :email => "Lilly.B.Brady@mailinator.com", :birthday => "1972/2/23 00:00:00" | ||
| 484 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "T", :last_name => "Harvey", :street_address => "85 Corio Street", :city => "Wensleydale", :state => "VIC", :postcode => "3241", :email => "Francesca.T.Harvey@mailinator.com", :birthday => "1985/9/9 00:00:00" | ||
| 485 | Person.create :gender => "male", :first_name => "Oliver", :middle_initial => "L", :last_name => "Davey", :street_address => "3 Monteagle Road", :city => "Braddon", :state => "ACT", :postcode => "2612", :email => "Oliver.L.Davey@dodgit.com", :birthday => "1979/6/18 00:00:00" | ||
| 486 | Person.create :gender => "male", :first_name => "Taylor", :middle_initial => "L", :last_name => "Ferguson", :street_address => "67 Norton Street", :city => "Spit Junction", :state => "NSW", :postcode => "2088", :email => "Taylor.L.Ferguson@trashymail.com", :birthday => "1974/12/27 00:00:00" | ||
| 487 | Person.create :gender => "female", :first_name => "Sarah", :middle_initial => "F", :last_name => "Slater", :street_address => "39 Faunce Crescent", :city => "Burgooney", :state => "NSW", :postcode => "2672", :email => "Sarah.F.Slater@spambob.com", :birthday => "1944/2/25 00:00:00" | ||
| 488 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "M", :last_name => "Connolly", :street_address => "85 Chapman Avenue", :city => "Duckmaloi", :state => "NSW", :postcode => "2787", :email => "Ava.M.Connolly@dodgit.com", :birthday => "1984/9/13 00:00:00" | ||
| 489 | Person.create :gender => "female", :first_name => "Summer", :middle_initial => "J", :last_name => "Higgins", :street_address => "45 Farnell Street", :city => "Cumnock", :state => "NSW", :postcode => "2867", :email => "Summer.J.Higgins@pookmail.com", :birthday => "1964/8/23 00:00:00" | ||
| 490 | Person.create :gender => "male", :first_name => "Alfie", :middle_initial => "A", :last_name => "Quinn", :street_address => "81 Pipeclay Road", :city => "Debenham", :state => "NSW", :postcode => "2446", :email => "Alfie.A.Quinn@dodgit.com", :birthday => "1956/9/26 00:00:00" | ||
| 491 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "R", :last_name => "White", :street_address => "40 Benny Street", :city => "Paloona", :state => "TAS", :postcode => "7310", :email => "Isabelle.R.White@pookmail.com", :birthday => "1980/7/12 00:00:00" | ||
| 492 | Person.create :gender => "female", :first_name => "Madison", :middle_initial => "L", :last_name => "Turnbull", :street_address => "14 Shell Road", :city => "Big Hill", :state => "VIC", :postcode => "3231", :email => "Madison.L.Turnbull@dodgit.com", :birthday => "1962/8/21 00:00:00" | ||
| 493 | Person.create :gender => "male", :first_name => "Callum", :middle_initial => "J", :last_name => "Dunn", :street_address => "24 Cornish Street", :city => "Chartwell", :state => "VIC", :postcode => "3030", :email => "Callum.J.Dunn@spambob.com", :birthday => "1956/6/20 00:00:00" | ||
| 494 | Person.create :gender => "male", :first_name => "Jamie", :middle_initial => "R", :last_name => "Ford", :street_address => "67 Eshelby Drive", :city => "Saunders Beach", :state => "QLD", :postcode => "4818", :email => "Jamie.R.Ford@pookmail.com", :birthday => "1981/11/21 00:00:00" | ||
| 495 | Person.create :gender => "male", :first_name => "James", :middle_initial => "S", :last_name => "Chamberlain", :street_address => "44 Boonah Qld", :city => "Fulham", :state => "QLD", :postcode => "4313", :email => "James.S.Chamberlain@pookmail.com", :birthday => "1951/2/4 00:00:00" | ||
| 496 | Person.create :gender => "male", :first_name => "Adam", :middle_initial => "S", :last_name => "Fuller", :street_address => "19 Devon Street", :city => "Marleston Dc", :state => "SA", :postcode => "5033", :email => "Adam.S.Fuller@mailinator.com", :birthday => "1976/11/11 00:00:00" | ||
| 497 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "J", :last_name => "Farmer", :street_address => "1 Walters Street", :city => "Benalla West", :state => "VIC", :postcode => "3672", :email => "Zachary.J.Farmer@trashymail.com", :birthday => "1980/12/16 00:00:00" | ||
| 498 | Person.create :gender => "male", :first_name => "Alexander", :middle_initial => "F", :last_name => "Kent", :street_address => "28 Maritime Avenue", :city => "Leeuwin", :state => "WA", :postcode => "6290", :email => "Alexander.F.Kent@trashymail.com", :birthday => "1947/6/19 00:00:00" | ||
| 499 | Person.create :gender => "female", :first_name => "Kayleigh", :middle_initial => "J", :last_name => "Sharp", :street_address => "63 Loris Way", :city => "Cuballing", :state => "WA", :postcode => "6311", :email => "Kayleigh.J.Sharp@pookmail.com", :birthday => "1954/7/31 00:00:00" | ||
| 500 | Person.create :gender => "male", :first_name => "Henry", :middle_initial => "M", :last_name => "Howe", :street_address => "23 Fergusson Street", :city => "Backmede", :state => "NSW", :postcode => "2470", :email => "Henry.M.Howe@dodgit.com", :birthday => "1966/3/7 00:00:00" | ||
| 501 | Person.create :gender => "female", :first_name => "Ruby", :middle_initial => "J", :last_name => "Barton", :street_address => "37 Glenpark Road", :city => "Lower Bucca", :state => "NSW", :postcode => "2450", :email => "Ruby.J.Barton@dodgit.com", :birthday => "1968/11/18 00:00:00" | ||
| 502 | Person.create :gender => "female", :first_name => "Jade", :middle_initial => "H", :last_name => "Sullivan", :street_address => "87 Thyme Avenue", :city => "Pilton", :state => "QLD", :postcode => "4361", :email => "Jade.H.Sullivan@mailinator.com", :birthday => "1979/7/14 00:00:00" | ||
| 503 | Person.create :gender => "male", :first_name => "Harvey", :middle_initial => "E", :last_name => "Law", :street_address => "13 Panorama Road", :city => "Woolomin", :state => "NSW", :postcode => "2340", :email => "Harvey.E.Law@pookmail.com", :birthday => "1959/4/30 00:00:00" | ||
| 504 | Person.create :gender => "male", :first_name => "Logan", :middle_initial => "A", :last_name => "Riley", :street_address => "46 Darwinia Loop", :city => "Nanutarra", :state => "WA", :postcode => "6751", :email => "Logan.A.Riley@pookmail.com", :birthday => "1951/10/14 00:00:00" | ||
| 505 | Person.create :gender => "male", :first_name => "Patrick", :middle_initial => "P", :last_name => "Johnson", :street_address => "92 Daly Terrace", :city => "Kinross", :state => "WA", :postcode => "6028", :email => "Patrick.P.Johnson@pookmail.com", :birthday => "1950/2/13 00:00:00" | ||
| 506 | Person.create :gender => "female", :first_name => "Sarah", :middle_initial => "M", :last_name => "Joyce", :street_address => "59 High Street", :city => "Bluff Beach", :state => "SA", :postcode => "5575", :email => "Sarah.M.Joyce@mailinator.com", :birthday => "1985/11/20 00:00:00" | ||
| 507 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "N", :last_name => "Morley", :street_address => "85 Saggers Road", :city => "Walyurin", :state => "WA", :postcode => "6363", :email => "Tom.N.Morley@trashymail.com", :birthday => "1959/12/19 00:00:00" | ||
| 508 | Person.create :gender => "female", :first_name => "Emily", :middle_initial => "C", :last_name => "Andrews", :street_address => "68 Souttar Terrace", :city => "Herdsman", :state => "WA", :postcode => "6017", :email => "Emily.C.Andrews@trashymail.com", :birthday => "1971/4/1 00:00:00" | ||
| 509 | Person.create :gender => "male", :first_name => "Finlay", :middle_initial => "K", :last_name => "James", :street_address => "22 Blairgowrie Avenue", :city => "Middle Flat", :state => "NSW", :postcode => "2630", :email => "Finlay.K.James@spambob.com", :birthday => "1955/12/25 00:00:00" | ||
| 510 | Person.create :gender => "female", :first_name => "Victoria", :middle_initial => "S", :last_name => "Lee", :street_address => "96 Yangan Drive", :city => "Colly Blue", :state => "NSW", :postcode => "2343", :email => "Victoria.S.Lee@mailinator.com", :birthday => "1968/3/1 00:00:00" | ||
| 511 | Person.create :gender => "male", :first_name => "Harry", :middle_initial => "E", :last_name => "Dunn", :street_address => "51 Myrtle Street", :city => "Bungeet", :state => "VIC", :postcode => "3726", :email => "Harry.E.Dunn@pookmail.com", :birthday => "1981/1/7 00:00:00" | ||
| 512 | Person.create :gender => "male", :first_name => "Joseph", :middle_initial => "H", :last_name => "Banks", :street_address => "35 Plug Street", :city => "New Valley", :state => "NSW", :postcode => "2365", :email => "Joseph.H.Banks@dodgit.com", :birthday => "1941/11/17 00:00:00" | ||
| 513 | Person.create :gender => "male", :first_name => "Logan", :middle_initial => "M", :last_name => "Gardiner", :street_address => "86 Mnimbah Road", :city => "Callaghan", :state => "NSW", :postcode => "2308", :email => "Logan.M.Gardiner@trashymail.com", :birthday => "1970/4/15 00:00:00" | ||
| 514 | Person.create :gender => "male", :first_name => "Max", :middle_initial => "E", :last_name => "Mills", :street_address => "45 Hart Street", :city => "Upper Rouchel", :state => "NSW", :postcode => "2336", :email => "Max.E.Mills@dodgit.com", :birthday => "1956/11/28 00:00:00" | ||
| 515 | Person.create :gender => "female", :first_name => "Sarah", :middle_initial => "H", :last_name => "Grant", :street_address => "22 Cambridge Street", :city => "Grose Wold", :state => "NSW", :postcode => "2753", :email => "Sarah.H.Grant@spambob.com", :birthday => "1985/12/29 00:00:00" | ||
| 516 | Person.create :gender => "male", :first_name => "Harley", :middle_initial => "L", :last_name => "Fraser", :street_address => "70 Border Drive", :city => "Euberta", :state => "NSW", :postcode => "2650", :email => "Harley.L.Fraser@mailinator.com", :birthday => "1959/10/1 00:00:00" | ||
| 517 | Person.create :gender => "female", :first_name => "Brooke", :middle_initial => "L", :last_name => "Reed", :street_address => "39 Burnley Street", :city => "Woodcroft", :state => "SA", :postcode => "5162", :email => "Brooke.L.Reed@spambob.com", :birthday => "1961/9/17 00:00:00" | ||
| 518 | Person.create :gender => "female", :first_name => "Rebecca", :middle_initial => "R", :last_name => "Parkinson", :street_address => "79 Bourke Crescent", :city => "Antwerp", :state => "VIC", :postcode => "3414", :email => "Rebecca.R.Parkinson@trashymail.com", :birthday => "1985/2/6 00:00:00" | ||
| 519 | Person.create :gender => "male", :first_name => "Gabriel", :middle_initial => "F", :last_name => "Davison", :street_address => "10 Creek Street", :city => "Marmadua", :state => "QLD", :postcode => "4405", :email => "Gabriel.F.Davison@trashymail.com", :birthday => "1980/12/20 00:00:00" | ||
| 520 | Person.create :gender => "female", :first_name => "Chloe", :middle_initial => "S", :last_name => "Farrell", :street_address => "1 Nandewar Street", :city => "Coffs Harbour", :state => "NSW", :postcode => "2450", :email => "Chloe.S.Farrell@pookmail.com", :birthday => "1947/8/12 00:00:00" | ||
| 521 | Person.create :gender => "female", :first_name => "Tilly", :middle_initial => "M", :last_name => "Cartwright", :street_address => "23 Dossiter Street", :city => "Lemont", :state => "TAS", :postcode => "7120", :email => "Tilly.M.Cartwright@mailinator.com", :birthday => "1982/2/24 00:00:00" | ||
| 522 | Person.create :gender => "female", :first_name => "Naomi", :middle_initial => "D", :last_name => "Sullivan", :street_address => "54 Dabinett Road", :city => "Lake Carlet", :state => "SA", :postcode => "5238", :email => "Naomi.D.Sullivan@trashymail.com", :birthday => "1963/11/19 00:00:00" | ||
| 523 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "O", :last_name => "Bolton", :street_address => "8 Grey Street", :city => "Gascoyne Junction", :state => "WA", :postcode => "6705", :email => "Ava.O.Bolton@spambob.com", :birthday => "1978/11/5 00:00:00" | ||
| 524 | Person.create :gender => "female", :first_name => "Ruby", :middle_initial => "J", :last_name => "Parkin", :street_address => "27 Patton Street", :city => "Hawksburn", :state => "VIC", :postcode => "3142", :email => "Ruby.J.Parkin@pookmail.com", :birthday => "1977/9/4 00:00:00" | ||
| 525 | Person.create :gender => "female", :first_name => "Megan", :middle_initial => "J", :last_name => "Potts", :street_address => "2 Boughtman Street", :city => "Mulgrave", :state => "VIC", :postcode => "3170", :email => "Megan.J.Potts@pookmail.com", :birthday => "1978/8/7 00:00:00" | ||
| 526 | Person.create :gender => "male", :first_name => "Adam", :middle_initial => "M", :last_name => "Stephenson", :street_address => "5 Marlin Avenue", :city => "Jerrawa", :state => "NSW", :postcode => "2582", :email => "Adam.M.Stephenson@dodgit.com", :birthday => "1970/11/19 00:00:00" | ||
| 527 | Person.create :gender => "female", :first_name => "Rosie", :middle_initial => "M", :last_name => "Barlow", :street_address => "15 Paradise Falls Road", :city => "Waldara", :state => "VIC", :postcode => "3678", :email => "Rosie.M.Barlow@trashymail.com", :birthday => "1952/11/29 00:00:00" | ||
| 528 | Person.create :gender => "male", :first_name => "Robert", :middle_initial => "P", :last_name => "Stephens", :street_address => "58 Bayley Street", :city => "Pheasant Creek", :state => "VIC", :postcode => "3757", :email => "Robert.P.Stephens@spambob.com", :birthday => "1971/3/13 00:00:00" | ||
| 529 | Person.create :gender => "male", :first_name => "Kyle", :middle_initial => "T", :last_name => "Ferguson", :street_address => "54 Mnimbah Road", :city => "Cliftleigh", :state => "NSW", :postcode => "2321", :email => "Kyle.T.Ferguson@dodgit.com", :birthday => "1982/11/29 00:00:00" | ||
| 530 | Person.create :gender => "female", :first_name => "Anna", :middle_initial => "D", :last_name => "Hyde", :street_address => "20 Todd Street", :city => "Horrocks", :state => "WA", :postcode => "6535", :email => "Anna.D.Hyde@trashymail.com", :birthday => "1982/3/20 00:00:00" | ||
| 531 | Person.create :gender => "male", :first_name => "Luke", :middle_initial => "M", :last_name => "Stone", :street_address => "27 Avondale Drive", :city => "Tongarra", :state => "NSW", :postcode => "2527", :email => "Luke.M.Stone@trashymail.com", :birthday => "1974/8/13 00:00:00" | ||
| 532 | Person.create :gender => "male", :first_name => "Taylor", :middle_initial => "L", :last_name => "Miah", :street_address => "38 Feather Street", :city => "Mount Samson", :state => "QLD", :postcode => "4520", :email => "Taylor.L.Miah@dodgit.com", :birthday => "1983/11/24 00:00:00" | ||
| 533 | Person.create :gender => "male", :first_name => "Joseph", :middle_initial => "G", :last_name => "Kaur", :street_address => "73 Hill Street", :city => "Mount Rumney", :state => "TAS", :postcode => "7170", :email => "Joseph.G.Kaur@spambob.com", :birthday => "1984/12/14 00:00:00" | ||
| 534 | Person.create :gender => "male", :first_name => "Bailey", :middle_initial => "T", :last_name => "Wheeler", :street_address => "72 Chatsworth Drive", :city => "Welshpool Dc", :state => "WA", :postcode => "6106", :email => "Bailey.T.Wheeler@mailinator.com", :birthday => "1954/11/16 00:00:00" | ||
| 535 | Person.create :gender => "male", :first_name => "Jude", :middle_initial => "D", :last_name => "Browne", :street_address => "51 Davidson Street", :city => "Yarrabah", :state => "QLD", :postcode => "4871", :email => "Jude.D.Browne@spambob.com", :birthday => "1955/4/23 00:00:00" | ||
| 536 | Person.create :gender => "male", :first_name => "Patrick", :middle_initial => "E", :last_name => "Hale", :street_address => "36 Henry Moss Court", :city => "Jamestown", :state => "SA", :postcode => "5491", :email => "Patrick.E.Hale@trashymail.com", :birthday => "1951/3/23 00:00:00" | ||
| 537 | Person.create :gender => "male", :first_name => "Harvey", :middle_initial => "E", :last_name => "Barton", :street_address => "84 Round Drive", :city => "Buttaba", :state => "NSW", :postcode => "2283", :email => "Harvey.E.Barton@pookmail.com", :birthday => "1952/3/2 00:00:00" | ||
| 538 | Person.create :gender => "female", :first_name => "Isobel", :middle_initial => "J", :last_name => "Daly", :street_address => "65 Muscat Street", :city => "Bonnie Rock", :state => "WA", :postcode => "6479", :email => "Isobel.J.Daly@spambob.com", :birthday => "1968/12/12 00:00:00" | ||
| 539 | Person.create :gender => "male", :first_name => "Brandon", :middle_initial => "S", :last_name => "Perry", :street_address => "70 Watson Street", :city => "Nanneella", :state => "VIC", :postcode => "3561", :email => "Brandon.S.Perry@trashymail.com", :birthday => "1959/1/19 00:00:00" | ||
| 540 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "L", :last_name => "Gray", :street_address => "85 Old Tenterfield Road", :city => "Warregah Island", :state => "NSW", :postcode => "2469", :email => "Tegan.L.Gray@spambob.com", :birthday => "1954/4/11 00:00:00" | ||
| 541 | Person.create :gender => "female", :first_name => "Nicole", :middle_initial => "A", :last_name => "Watkins", :street_address => "14 Cherry Grove", :city => "Brittons Swamp", :state => "TAS", :postcode => "7330", :email => "Nicole.A.Watkins@mailinator.com", :birthday => "1950/7/7 00:00:00" | ||
| 542 | Person.create :gender => "male", :first_name => "Spencer", :middle_initial => "C", :last_name => "Black", :street_address => "24 Purcell Place", :city => "Dalmorton", :state => "NSW", :postcode => "2460", :email => "Spencer.C.Black@spambob.com", :birthday => "1979/5/7 00:00:00" | ||
| 543 | Person.create :gender => "female", :first_name => "Courtney", :middle_initial => "M", :last_name => "Hamilton", :street_address => "9 Hargrave Road", :city => "Blackbutt North", :state => "QLD", :postcode => "4306", :email => "Courtney.M.Hamilton@mailinator.com", :birthday => "1940/9/15 00:00:00" | ||
| 544 | Person.create :gender => "male", :first_name => "David", :middle_initial => "N", :last_name => "Davison", :street_address => "70 Railway Street", :city => "Greenmount East", :state => "QLD", :postcode => "4359", :email => "David.N.Davison@mailinator.com", :birthday => "1967/1/28 00:00:00" | ||
| 545 | Person.create :gender => "male", :first_name => "Leon", :middle_initial => "O", :last_name => "Jarvis", :street_address => "62 Shell Road", :city => "Carlisle River", :state => "VIC", :postcode => "3239", :email => "Leon.O.Jarvis@trashymail.com", :birthday => "1949/7/4 00:00:00" | ||
| 546 | Person.create :gender => "female", :first_name => "Bethany", :middle_initial => "L", :last_name => "Henderson", :street_address => "30 Meyer Road", :city => "Gomersal", :state => "SA", :postcode => "5352", :email => "Bethany.L.Henderson@mailinator.com", :birthday => "1955/8/19 00:00:00" | ||
| 547 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "M", :last_name => "Stokes", :street_address => "83 Adavale Road", :city => "Mummel", :state => "NSW", :postcode => "2580", :email => "Louie.M.Stokes@mailinator.com", :birthday => "1948/11/7 00:00:00" | ||
| 548 | Person.create :gender => "female", :first_name => "Eve", :middle_initial => "J", :last_name => "Richards", :street_address => "86 Hill Street", :city => "Tunbridge", :state => "TAS", :postcode => "7120", :email => "Eve.J.Richards@dodgit.com", :birthday => "1965/5/22 00:00:00" | ||
| 549 | Person.create :gender => "female", :first_name => "Bethany", :middle_initial => "S", :last_name => "Perkins", :street_address => "56 Peterho Boulevard", :city => "Ward Belt", :state => "SA", :postcode => "5118", :email => "Bethany.S.Perkins@mailinator.com", :birthday => "1967/10/7 00:00:00" | ||
| 550 | Person.create :gender => "male", :first_name => "Cameron", :middle_initial => "L", :last_name => "Lambert", :street_address => "33 Farnell Street", :city => "Obley", :state => "NSW", :postcode => "2868", :email => "Cameron.L.Lambert@trashymail.com", :birthday => "1955/1/20 00:00:00" | ||
| 551 | Person.create :gender => "female", :first_name => "Courtney", :middle_initial => "C", :last_name => "Bishop", :street_address => "11 Burnley Street", :city => "Seaford Heights", :state => "SA", :postcode => "5169", :email => "Courtney.C.Bishop@spambob.com", :birthday => "1947/12/16 00:00:00" | ||
| 552 | Person.create :gender => "male", :first_name => "Thomas", :middle_initial => "S", :last_name => "Harper", :street_address => "77 Bathurst Road", :city => "Perthville", :state => "NSW", :postcode => "2795", :email => "Thomas.S.Harper@trashymail.com", :birthday => "1970/10/30 00:00:00" | ||
| 553 | Person.create :gender => "male", :first_name => "Ryan", :middle_initial => "E", :last_name => "Barnes", :street_address => "25 McLachlan Street", :city => "Quantong", :state => "VIC", :postcode => "3401", :email => "Ryan.E.Barnes@dodgit.com", :birthday => "1961/4/29 00:00:00" | ||
| 554 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "A", :last_name => "Coates", :street_address => "89 Sunnyside Road", :city => "Stockyard Plain", :state => "SA", :postcode => "5330", :email => "Tom.A.Coates@mailinator.com", :birthday => "1944/2/19 00:00:00" | ||
| 555 | Person.create :gender => "female", :first_name => "Isabella", :middle_initial => "L", :last_name => "Clarke", :street_address => "6 Hummocky Road", :city => "Gosse", :state => "SA", :postcode => "5223", :email => "Isabella.L.Clarke@pookmail.com", :birthday => "1953/5/26 00:00:00" | ||
| 556 | Person.create :gender => "female", :first_name => "Georgina", :middle_initial => "B", :last_name => "Rowley", :street_address => "66 Shadforth Street", :city => "Teal Point", :state => "VIC", :postcode => "3579", :email => "Georgina.B.Rowley@trashymail.com", :birthday => "1983/12/14 00:00:00" | ||
| 557 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "D", :last_name => "Howard", :street_address => "57 Mildura Street", :city => "Four Mile Creek", :state => "TAS", :postcode => "7215", :email => "Maddison.D.Howard@pookmail.com", :birthday => "1962/12/3 00:00:00" | ||
| 558 | Person.create :gender => "female", :first_name => "Bethany", :middle_initial => "A", :last_name => "Hamilton", :street_address => "91 Amiens Road", :city => "Erudgere", :state => "NSW", :postcode => "2850", :email => "Bethany.A.Hamilton@trashymail.com", :birthday => "1965/5/20 00:00:00" | ||
| 559 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "C", :last_name => "Duffy", :street_address => "3 Glen William Road", :city => "Crystalbrook", :state => "QLD", :postcode => "4871", :email => "Christopher.C.Duffy@trashymail.com", :birthday => "1966/4/25 00:00:00" | ||
| 560 | Person.create :gender => "male", :first_name => "Rhys", :middle_initial => "E", :last_name => "Bird", :street_address => "12 Daly Terrace", :city => "Caraban", :state => "WA", :postcode => "6041", :email => "Rhys.E.Bird@spambob.com", :birthday => "1946/10/7 00:00:00" | ||
| 561 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "S", :last_name => "Moss", :street_address => "42 Quoin Road", :city => "Karoola", :state => "TAS", :postcode => "7267", :email => "Jake.S.Moss@spambob.com", :birthday => "1961/1/2 00:00:00" | ||
| 562 | Person.create :gender => "female", :first_name => "Lily", :middle_initial => "T", :last_name => "Harris", :street_address => "23 Feather Street", :city => "Dayboro", :state => "QLD", :postcode => "4521", :email => "Lily.T.Harris@trashymail.com", :birthday => "1950/3/20 00:00:00" | ||
| 563 | Person.create :gender => "female", :first_name => "Imogen", :middle_initial => "D", :last_name => "Fox", :street_address => "80 Porana Place", :city => "Tardun", :state => "WA", :postcode => "6628", :email => "Imogen.D.Fox@dodgit.com", :birthday => "1963/6/24 00:00:00" | ||
| 564 | Person.create :gender => "female", :first_name => "Eve", :middle_initial => "A", :last_name => "Barber", :street_address => "40 Frouds Road", :city => "Bundara", :state => "VIC", :postcode => "3898", :email => "Eve.A.Barber@dodgit.com", :birthday => "1979/11/11 00:00:00" | ||
| 565 | Person.create :gender => "female", :first_name => "Bethany", :middle_initial => "L", :last_name => "Moran", :street_address => "79 Norton Street", :city => "Brooklyn", :state => "NSW", :postcode => "2083", :email => "Bethany.L.Moran@trashymail.com", :birthday => "1954/11/24 00:00:00" | ||
| 566 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "R", :last_name => "Marshall", :street_address => "7 Duff Street", :city => "Orange Springs", :state => "WA", :postcode => "6503", :email => "Ava.R.Marshall@pookmail.com", :birthday => "1964/12/26 00:00:00" | ||
| 567 | Person.create :gender => "female", :first_name => "Scarlett", :middle_initial => "I", :last_name => "Byrne", :street_address => "33 Henley Beach Road", :city => "Trott Park", :state => "SA", :postcode => "5158", :email => "Scarlett.I.Byrne@dodgit.com", :birthday => "1976/8/3 00:00:00" | ||
| 568 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "L", :last_name => "Conway", :street_address => "67 Gregory Way", :city => "Allanson", :state => "WA", :postcode => "6225", :email => "Tegan.L.Conway@dodgit.com", :birthday => "1954/2/9 00:00:00" | ||
| 569 | Person.create :gender => "female", :first_name => "Katherine", :middle_initial => "R", :last_name => "Lucas", :street_address => "95 Bathurst Road", :city => "Wattle Flat", :state => "NSW", :postcode => "2795", :email => "Katherine.R.Lucas@dodgit.com", :birthday => "1947/9/4 00:00:00" | ||
| 570 | Person.create :gender => "female", :first_name => "Amy", :middle_initial => "S", :last_name => "Chamberlain", :street_address => "32 Marx Hill Road", :city => "Upper Kalang", :state => "NSW", :postcode => "2454", :email => "Amy.S.Chamberlain@spambob.com", :birthday => "1982/2/17 00:00:00" | ||
| 571 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "N", :last_name => "McLean", :street_address => "3 Mt Berryman Road", :city => "Lockyer", :state => "QLD", :postcode => "4344", :email => "Tom.N.McLean@pookmail.com", :birthday => "1984/2/20 00:00:00" | ||
| 572 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "E", :last_name => "George", :street_address => "47 Holthouse Road", :city => "Forreston", :state => "SA", :postcode => "5233", :email => "Owen.E.George@spambob.com", :birthday => "1970/5/11 00:00:00" | ||
| 573 | Person.create :gender => "male", :first_name => "Finlay", :middle_initial => "P", :last_name => "Black", :street_address => "64 Taylor Street", :city => "Naring", :state => "VIC", :postcode => "3636", :email => "Finlay.P.Black@spambob.com", :birthday => "1980/7/2 00:00:00" | ||
| 574 | Person.create :gender => "male", :first_name => "George", :middle_initial => "A", :last_name => "Rees", :street_address => "39 Millicent Drive", :city => "Brownmore", :state => "NSW", :postcode => "2420", :email => "George.A.Rees@dodgit.com", :birthday => "1974/5/26 00:00:00" | ||
| 575 | Person.create :gender => "male", :first_name => "Cameron", :middle_initial => "L", :last_name => "Walker", :street_address => "26 Wallis Street", :city => "Dover Heights", :state => "NSW", :postcode => "2030", :email => "Cameron.L.Walker@dodgit.com", :birthday => "1963/4/12 00:00:00" | ||
| 576 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "J", :last_name => "Howarth", :street_address => "68 Flinstone Drive", :city => "Hermitage", :state => "TAS", :postcode => "7030", :email => "Shannon.J.Howarth@pookmail.com", :birthday => "1952/11/19 00:00:00" | ||
| 577 | Person.create :gender => "female", :first_name => "Aaliyah", :middle_initial => "R", :last_name => "Austin", :street_address => "6 Faulkner Street", :city => "Duval", :state => "NSW", :postcode => "2350", :email => "Aaliyah.R.Austin@dodgit.com", :birthday => "1970/6/28 00:00:00" | ||
| 578 | Person.create :gender => "male", :first_name => "Louis", :middle_initial => "C", :last_name => "Kennedy", :street_address => "10 Old Tenterfield Road", :city => "Mummulgum", :state => "NSW", :postcode => "2469", :email => "Louis.C.Kennedy@dodgit.com", :birthday => "1960/5/28 00:00:00" | ||
| 579 | Person.create :gender => "female", :first_name => "Bethany", :middle_initial => "A", :last_name => "Hunt", :street_address => "81 Reynolds Road", :city => "Lake Borumba", :state => "QLD", :postcode => "4570", :email => "Bethany.A.Hunt@dodgit.com", :birthday => "1962/5/2 00:00:00" | ||
| 580 | Person.create :gender => "male", :first_name => "Joseph", :middle_initial => "A", :last_name => "Poole", :street_address => "57 Lewin Street", :city => "Mount Crystal", :state => "NSW", :postcode => "2665", :email => "Joseph.A.Poole@trashymail.com", :birthday => "1960/12/13 00:00:00" | ||
| 581 | Person.create :gender => "male", :first_name => "Luca", :middle_initial => "G", :last_name => "Harper", :street_address => "87 Villeneuve Street", :city => "Eurobin", :state => "VIC", :postcode => "3739", :email => "Luca.G.Harper@spambob.com", :birthday => "1965/11/26 00:00:00" | ||
| 582 | Person.create :gender => "female", :first_name => "Georgia", :middle_initial => "E", :last_name => "Bull", :street_address => "66 Cedar Street", :city => "Trebonne", :state => "QLD", :postcode => "4850", :email => "Georgia.E.Bull@dodgit.com", :birthday => "1983/4/19 00:00:00" | ||
| 583 | Person.create :gender => "male", :first_name => "Jude", :middle_initial => "L", :last_name => "Kemp", :street_address => "70 Hunter Street", :city => "North Toowoomba", :state => "QLD", :postcode => "4350", :email => "Jude.L.Kemp@spambob.com", :birthday => "1956/12/20 00:00:00" | ||
| 584 | Person.create :gender => "female", :first_name => "Eva", :middle_initial => "B", :last_name => "Anderson", :street_address => "82 Campbells River Road", :city => "Cryon", :state => "NSW", :postcode => "2832", :email => "Eva.B.Anderson@dodgit.com", :birthday => "1958/10/18 00:00:00" | ||
| 585 | Person.create :gender => "female", :first_name => "Poppy", :middle_initial => "A", :last_name => "Lynch", :street_address => "19 Darwinia Loop", :city => "Gingerah", :state => "WA", :postcode => "6725", :email => "Poppy.A.Lynch@spambob.com", :birthday => "1957/11/15 00:00:00" | ||
| 586 | Person.create :gender => "female", :first_name => "Katherine", :middle_initial => "J", :last_name => "Power", :street_address => "7 Peterho Boulevard", :city => "Concordia", :state => "SA", :postcode => "5118", :email => "Katherine.J.Power@spambob.com", :birthday => "1965/4/7 00:00:00" | ||
| 587 | Person.create :gender => "female", :first_name => "Ellie", :middle_initial => "B", :last_name => "Cross", :street_address => "18 Boughtman Street", :city => "Hopetoun Gardens", :state => "VIC", :postcode => "3162", :email => "Ellie.B.Cross@dodgit.com", :birthday => "1983/5/4 00:00:00" | ||
| 588 | Person.create :gender => "female", :first_name => "Eleanor", :middle_initial => "A", :last_name => "Riley", :street_address => "67 Boland Drive", :city => "Lennox Head", :state => "NSW", :postcode => "2478", :email => "Eleanor.A.Riley@mailinator.com", :birthday => "1965/2/26 00:00:00" | ||
| 589 | Person.create :gender => "female", :first_name => "Lola", :middle_initial => "S", :last_name => "Reynolds", :street_address => "92 Grey Street", :city => "Carbla", :state => "WA", :postcode => "6701", :email => "Lola.S.Reynolds@mailinator.com", :birthday => "1957/7/13 00:00:00" | ||
| 590 | Person.create :gender => "male", :first_name => "Hayden", :middle_initial => "L", :last_name => "Burton", :street_address => "48 Millicent Drive", :city => "Torryburn", :state => "NSW", :postcode => "2421", :email => "Hayden.L.Burton@spambob.com", :birthday => "1959/1/6 00:00:00" | ||
| 591 | Person.create :gender => "female", :first_name => "Elizabeth", :middle_initial => "P", :last_name => "O'eill", :street_address => "71 Grey Street", :city => "Brown Range", :state => "WA", :postcode => "6701", :email => "Elizabeth.P.O'eill@dodgit.com", :birthday => "1983/6/3 00:00:00" | ||
| 592 | Person.create :gender => "female", :first_name => "Ruby", :middle_initial => "H", :last_name => "Rose", :street_address => "9 Gadd Avenue", :city => "Port Pirie", :state => "SA", :postcode => "5540", :email => "Ruby.H.Rose@spambob.com", :birthday => "1968/2/2 00:00:00" | ||
| 593 | Person.create :gender => "male", :first_name => "Tyler", :middle_initial => "T", :last_name => "Hargreaves", :street_address => "89 Plantation Place", :city => "Arkell", :state => "NSW", :postcode => "2795", :email => "Tyler.T.Hargreaves@trashymail.com", :birthday => "1963/2/13 00:00:00" | ||
| 594 | Person.create :gender => "male", :first_name => "Joseph", :middle_initial => "E", :last_name => "Thomas", :street_address => "61 Wigley Street", :city => "South Plympton", :state => "SA", :postcode => "5038", :email => "Joseph.E.Thomas@mailinator.com", :birthday => "1974/4/16 00:00:00" | ||
| 595 | Person.create :gender => "female", :first_name => "Lilly", :middle_initial => "J", :last_name => "Power", :street_address => "31 Dalgarno Street", :city => "Maules Creek", :state => "NSW", :postcode => "2382", :email => "Lilly.J.Power@dodgit.com", :birthday => "1976/7/28 00:00:00" | ||
| 596 | Person.create :gender => "female", :first_name => "Caitlin", :middle_initial => "D", :last_name => "Wright", :street_address => "73 Saggers Road", :city => "Dudinin", :state => "WA", :postcode => "6363", :email => "Caitlin.D.Wright@dodgit.com", :birthday => "1970/6/18 00:00:00" | ||
| 597 | Person.create :gender => "female", :first_name => "Eve", :middle_initial => "D", :last_name => "Pope", :street_address => "66 Kopkes Road", :city => "Carngham", :state => "VIC", :postcode => "3351", :email => "Eve.D.Pope@dodgit.com", :birthday => "1942/2/11 00:00:00" | ||
| 598 | Person.create :gender => "male", :first_name => "Taylor", :middle_initial => "T", :last_name => "Dunn", :street_address => "50 Cambridge Street", :city => "Central Colo", :state => "NSW", :postcode => "2756", :email => "Taylor.T.Dunn@dodgit.com", :birthday => "1973/3/19 00:00:00" | ||
| 599 | Person.create :gender => "female", :first_name => "Alice", :middle_initial => "H", :last_name => "Cox", :street_address => "48 Chatsworth Drive", :city => "Seville Grove", :state => "WA", :postcode => "6112", :email => "Alice.H.Cox@mailinator.com", :birthday => "1973/4/25 00:00:00" | ||
| 600 | Person.create :gender => "female", :first_name => "Eva", :middle_initial => "A", :last_name => "Kemp", :street_address => "37 Healy Road", :city => "Lowden", :state => "WA", :postcode => "6240", :email => "Eva.A.Kemp@mailinator.com", :birthday => "1963/7/12 00:00:00" | ||
| 601 | Person.create :gender => "female", :first_name => "Maisie", :middle_initial => "K", :last_name => "Doyle", :street_address => "61 Martens Place", :city => "Amity Point", :state => "QLD", :postcode => "4183", :email => "Maisie.K.Doyle@dodgit.com", :birthday => "1951/9/5 00:00:00" | ||
| 602 | Person.create :gender => "male", :first_name => "Mohammad", :middle_initial => "L", :last_name => "Ellis", :street_address => "85 Little Myers Street", :city => "Coimadai", :state => "VIC", :postcode => "3340", :email => "Mohammad.L.Ellis@spambob.com", :birthday => "1962/10/20 00:00:00" | ||
| 603 | Person.create :gender => "male", :first_name => "Tyler", :middle_initial => "K", :last_name => "Foster", :street_address => "85 Ashton Road", :city => "Boolading", :state => "WA", :postcode => "6392", :email => "Tyler.K.Foster@trashymail.com", :birthday => "1977/4/18 00:00:00" | ||
| 604 | Person.create :gender => "male", :first_name => "Benjamin", :middle_initial => "F", :last_name => "Ross", :street_address => "45 Fernleigh Ave", :city => "Goodooga", :state => "NSW", :postcode => "2831", :email => "Benjamin.F.Ross@pookmail.com", :birthday => "1944/11/8 00:00:00" | ||
| 605 | Person.create :gender => "female", :first_name => "Kate", :middle_initial => "C", :last_name => "Pope", :street_address => "55 Punchs Creek Road", :city => "Silver Spur", :state => "QLD", :postcode => "4385", :email => "Kate.C.Pope@trashymail.com", :birthday => "1971/5/25 00:00:00" | ||
| 606 | Person.create :gender => "male", :first_name => "Ewan", :middle_initial => "K", :last_name => "Whittaker", :street_address => "61 Quoin Road", :city => "Gravelly Beach", :state => "TAS", :postcode => "7276", :email => "Ewan.K.Whittaker@dodgit.com", :birthday => "1963/4/11 00:00:00" | ||
| 607 | Person.create :gender => "male", :first_name => "Jamie", :middle_initial => "E", :last_name => "Andrews", :street_address => "52 Little Myers Street", :city => "Larralea", :state => "VIC", :postcode => "3325", :email => "Jamie.E.Andrews@mailinator.com", :birthday => "1950/7/15 00:00:00" | ||
| 608 | Person.create :gender => "female", :first_name => "Amelia", :middle_initial => "R", :last_name => "Smith", :street_address => "51 Wharf St", :city => "East Gosford", :state => "NSW", :postcode => "2250", :email => "Amelia.R.Smith@pookmail.com", :birthday => "1983/6/19 00:00:00" | ||
| 609 | Person.create :gender => "male", :first_name => "Sean", :middle_initial => "J", :last_name => "Savage", :street_address => "68 Main Street", :city => "Woodleigh", :state => "SA", :postcode => "5311", :email => "Sean.J.Savage@mailinator.com", :birthday => "1962/4/16 00:00:00" | ||
| 610 | Person.create :gender => "male", :first_name => "Callum", :middle_initial => "L", :last_name => "Cook", :street_address => "42 Moruya Street", :city => "Doon Doon", :state => "NSW", :postcode => "2484", :email => "Callum.L.Cook@dodgit.com", :birthday => "1965/2/12 00:00:00" | ||
| 611 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "E", :last_name => "Atkinson", :street_address => "36 Mildura Street", :city => "Goulds Country", :state => "TAS", :postcode => "7216", :email => "Jacob.E.Atkinson@trashymail.com", :birthday => "1945/6/21 00:00:00" | ||
| 612 | Person.create :gender => "female", :first_name => "Shannon", :middle_initial => "B", :last_name => "Francis", :street_address => "72 Chapman Avenue", :city => "Bumbaldry", :state => "NSW", :postcode => "2794", :email => "Shannon.B.Francis@mailinator.com", :birthday => "1960/7/2 00:00:00" | ||
| 613 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "A", :last_name => "Chambers", :street_address => "66 McPherson Road", :city => "Mount Beauty", :state => "VIC", :postcode => "3699", :email => "Louie.A.Chambers@spambob.com", :birthday => "1957/8/5 00:00:00" | ||
| 614 | Person.create :gender => "female", :first_name => "Caitlin", :middle_initial => "C", :last_name => "Butler", :street_address => "61 Bayley Street", :city => "Dixons Creek", :state => "VIC", :postcode => "3775", :email => "Caitlin.C.Butler@mailinator.com", :birthday => "1954/8/13 00:00:00" | ||
| 615 | Person.create :gender => "male", :first_name => "Thomas", :middle_initial => "I", :last_name => "Ellis", :street_address => "3 Ugoa Street", :city => "Forster Shopping Village", :state => "NSW", :postcode => "2428", :email => "Thomas.I.Ellis@spambob.com", :birthday => "1981/1/21 00:00:00" | ||
| 616 | Person.create :gender => "male", :first_name => "William", :middle_initial => "N", :last_name => "Brennan", :street_address => "64 Bayley Street", :city => "Whittlesea", :state => "VIC", :postcode => "3757", :email => "William.N.Brennan@spambob.com", :birthday => "1956/1/6 00:00:00" | ||
| 617 | Person.create :gender => "male", :first_name => "Hayden", :middle_initial => "A", :last_name => "Barker", :street_address => "44 Boland Drive", :city => "Meerschaum Vale", :state => "NSW", :postcode => "2477", :email => "Hayden.A.Barker@pookmail.com", :birthday => "1958/11/22 00:00:00" | ||
| 618 | Person.create :gender => "male", :first_name => "Aaron", :middle_initial => "T", :last_name => "Phillips", :street_address => "68 McLaughlin Road", :city => "Pine Mountain", :state => "QLD", :postcode => "4306", :email => "Aaron.T.Phillips@pookmail.com", :birthday => "1956/5/4 00:00:00" | ||
| 619 | Person.create :gender => "female", :first_name => "Madeleine", :middle_initial => "G", :last_name => "Flynn", :street_address => "51 Begley Street", :city => "Howitt", :state => "QLD", :postcode => "4890", :email => "Madeleine.G.Flynn@pookmail.com", :birthday => "1959/6/30 00:00:00" | ||
| 620 | Person.create :gender => "male", :first_name => "Spencer", :middle_initial => "M", :last_name => "Harris", :street_address => "43 Nerrigundah Drive", :city => "Monomeith", :state => "VIC", :postcode => "3984", :email => "Spencer.M.Harris@spambob.com", :birthday => "1970/2/7 00:00:00" | ||
| 621 | Person.create :gender => "female", :first_name => "Paige", :middle_initial => "S", :last_name => "Chan", :street_address => "53 Queen Street", :city => "Oxford Falls", :state => "NSW", :postcode => "2100", :email => "Paige.S.Chan@trashymail.com", :birthday => "1944/3/1 00:00:00" | ||
| 622 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "J", :last_name => "Harrison", :street_address => "12 South Molle Boulevard", :city => "Damper Creek", :state => "QLD", :postcode => "4849", :email => "Francesca.J.Harrison@spambob.com", :birthday => "1978/2/21 00:00:00" | ||
| 623 | Person.create :gender => "female", :first_name => "Alexandra", :middle_initial => "T", :last_name => "Curtis", :street_address => "39 Kaesler Road", :city => "Clay Wells", :state => "SA", :postcode => "5280", :email => "Alexandra.T.Curtis@trashymail.com", :birthday => "1962/7/16 00:00:00" | ||
| 624 | Person.create :gender => "male", :first_name => "Alexander", :middle_initial => "H", :last_name => "Todd", :street_address => "48 Healy Road", :city => "Boyup Brook", :state => "WA", :postcode => "6244", :email => "Alexander.H.Todd@mailinator.com", :birthday => "1948/1/11 00:00:00" | ||
| 625 | Person.create :gender => "male", :first_name => "Louis", :middle_initial => "K", :last_name => "Lloyd", :street_address => "16 Little Myers Street", :city => "Cressy", :state => "VIC", :postcode => "3322", :email => "Louis.K.Lloyd@pookmail.com", :birthday => "1984/6/15 00:00:00" | ||
| 626 | Person.create :gender => "female", :first_name => "Katherine", :middle_initial => "B", :last_name => "Brennan", :street_address => "37 Spring Creek Road", :city => "Labertouche", :state => "VIC", :postcode => "3816", :email => "Katherine.B.Brennan@trashymail.com", :birthday => "1943/8/31 00:00:00" | ||
| 627 | Person.create :gender => "female", :first_name => "Sarah", :middle_initial => "B", :last_name => "Palmer", :street_address => "97 Kintyre Street", :city => "Springwood", :state => "QLD", :postcode => "4127", :email => "Sarah.B.Palmer@spambob.com", :birthday => "1962/12/8 00:00:00" | ||
| 628 | Person.create :gender => "female", :first_name => "Phoebe", :middle_initial => "J", :last_name => "Hartley", :street_address => "41 Rimbanda Road", :city => "Moggs Swamp", :state => "NSW", :postcode => "2370", :email => "Phoebe.J.Hartley@spambob.com", :birthday => "1977/1/29 00:00:00" | ||
| 629 | Person.create :gender => "female", :first_name => "Caitlin", :middle_initial => "O", :last_name => "Phillips", :street_address => "4 Henry Street", :city => "Highton", :state => "VIC", :postcode => "3216", :email => "Caitlin.O.Phillips@spambob.com", :birthday => "1968/6/8 00:00:00" | ||
| 630 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "M", :last_name => "Patel", :street_address => "29 Barker Street", :city => "Coblinine", :state => "WA", :postcode => "6317", :email => "Sam.M.Patel@mailinator.com", :birthday => "1983/11/3 00:00:00" | ||
| 631 | Person.create :gender => "male", :first_name => "Spencer", :middle_initial => "I", :last_name => "Bell", :street_address => "41 Quoin Road", :city => "Beaconsfield", :state => "TAS", :postcode => "7270", :email => "Spencer.I.Bell@spambob.com", :birthday => "1965/1/17 00:00:00" | ||
| 632 | Person.create :gender => "female", :first_name => "Kayleigh", :middle_initial => "A", :last_name => "Duncan", :street_address => "59 Corio Street", :city => "Barongarook West", :state => "VIC", :postcode => "3249", :email => "Kayleigh.A.Duncan@trashymail.com", :birthday => "1965/6/10 00:00:00" | ||
| 633 | Person.create :gender => "male", :first_name => "Muhammad", :middle_initial => "A", :last_name => "Duncan", :street_address => "65 Loris Way", :city => "Dumberning", :state => "WA", :postcode => "6312", :email => "Muhammad.A.Duncan@dodgit.com", :birthday => "1943/4/22 00:00:00" | ||
| 634 | Person.create :gender => "female", :first_name => "Isabella", :middle_initial => "S", :last_name => "Leach", :street_address => "27 Grey Street", :city => "Woodleigh", :state => "WA", :postcode => "6701", :email => "Isabella.S.Leach@mailinator.com", :birthday => "1959/3/19 00:00:00" | ||
| 635 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "E", :last_name => "Steele", :street_address => "89 Shirley Street", :city => "Studio Village", :state => "QLD", :postcode => "4210", :email => "Louie.E.Steele@pookmail.com", :birthday => "1954/1/13 00:00:00" | ||
| 636 | Person.create :gender => "male", :first_name => "William", :middle_initial => "C", :last_name => "Joyce", :street_address => "40 Cherry Grove", :city => "Scopus", :state => "TAS", :postcode => "7330", :email => "William.C.Joyce@mailinator.com", :birthday => "1964/10/24 00:00:00" | ||
| 637 | Person.create :gender => "male", :first_name => "Riley", :middle_initial => "C", :last_name => "Hyde", :street_address => "23 Edmundsons Road", :city => "Leigh Creek", :state => "VIC", :postcode => "3352", :email => "Riley.C.Hyde@spambob.com", :birthday => "1985/7/22 00:00:00" | ||
| 638 | Person.create :gender => "female", :first_name => "Madeleine", :middle_initial => "W", :last_name => "Coles", :street_address => "12 Rose Street", :city => "Clematis", :state => "VIC", :postcode => "3782", :email => "Madeleine.W.Coles@trashymail.com", :birthday => "1961/2/18 00:00:00" | ||
| 639 | Person.create :gender => "female", :first_name => "Erin", :middle_initial => "B", :last_name => "Conway", :street_address => "71 Lapko Road", :city => "Cowalellup", :state => "WA", :postcode => "6336", :email => "Erin.B.Conway@mailinator.com", :birthday => "1978/10/12 00:00:00" | ||
| 640 | Person.create :gender => "male", :first_name => "Kyle", :middle_initial => "Z", :last_name => "King", :street_address => "85 McLachlan Street", :city => "Brimpaen", :state => "VIC", :postcode => "3401", :email => "Kyle.Z.King@mailinator.com", :birthday => "1977/12/16 00:00:00" | ||
| 641 | Person.create :gender => "male", :first_name => "Charles", :middle_initial => "K", :last_name => "Bowen", :street_address => "32 Walpole Avenue", :city => "Nullawarre North", :state => "VIC", :postcode => "3268", :email => "Charles.K.Bowen@spambob.com", :birthday => "1945/11/24 00:00:00" | ||
| 642 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "F", :last_name => "Ferguson", :street_address => "62 Eshelby Drive", :city => "Rosslea", :state => "QLD", :postcode => "4812", :email => "Louie.F.Ferguson@mailinator.com", :birthday => "1953/11/20 00:00:00" | ||
| 643 | Person.create :gender => "male", :first_name => "Liam", :middle_initial => "G", :last_name => "McCarthy", :street_address => "81 Spencer Street", :city => "Pomona", :state => "QLD", :postcode => "4568", :email => "Liam.G.McCarthy@trashymail.com", :birthday => "1942/5/5 00:00:00" | ||
| 644 | Person.create :gender => "female", :first_name => "Holly", :middle_initial => "J", :last_name => "Kennedy", :street_address => "31 Learmouth Street", :city => "Lyons", :state => "VIC", :postcode => "3304", :email => "Holly.J.Kennedy@trashymail.com", :birthday => "1985/12/2 00:00:00" | ||
| 645 | Person.create :gender => "female", :first_name => "Lily", :middle_initial => "R", :last_name => "Hope", :street_address => "52 Shell Road", :city => "Glenaire", :state => "VIC", :postcode => "3238", :email => "Lily.R.Hope@mailinator.com", :birthday => "1969/1/18 00:00:00" | ||
| 646 | Person.create :gender => "male", :first_name => "Kyle", :middle_initial => "I", :last_name => "Hope", :street_address => "15 Peninsula Drive", :city => "Burraneer", :state => "NSW", :postcode => "2230", :email => "Kyle.I.Hope@pookmail.com", :birthday => "1982/3/18 00:00:00" | ||
| 647 | Person.create :gender => "male", :first_name => "Adam", :middle_initial => "A", :last_name => "Mann", :street_address => "14 Thyme Avenue", :city => "Spring Creek", :state => "QLD", :postcode => "4361", :email => "Adam.A.Mann@trashymail.com", :birthday => "1976/3/9 00:00:00" | ||
| 648 | Person.create :gender => "female", :first_name => "Isabel", :middle_initial => "N", :last_name => "Lowe", :street_address => "43 Thyme Avenue", :city => "Cottonvale", :state => "QLD", :postcode => "4375", :email => "Isabel.N.Lowe@dodgit.com", :birthday => "1982/9/1 00:00:00" | ||
| 649 | Person.create :gender => "male", :first_name => "Benjamin", :middle_initial => "S", :last_name => "Carter", :street_address => "10 Garden Place", :city => "Korong Vale", :state => "VIC", :postcode => "3520", :email => "Benjamin.S.Carter@dodgit.com", :birthday => "1952/8/27 00:00:00" | ||
| 650 | Person.create :gender => "female", :first_name => "Laura", :middle_initial => "J", :last_name => "Burns", :street_address => "46 Junction St", :city => "Conargo", :state => "NSW", :postcode => "2710", :email => "Laura.J.Burns@dodgit.com", :birthday => "1962/12/14 00:00:00" | ||
| 651 | Person.create :gender => "female", :first_name => "Maya", :middle_initial => "T", :last_name => "Ferguson", :street_address => "20 Glendonbrook Road", :city => "Upper Bylong", :state => "NSW", :postcode => "2849", :email => "Maya.T.Ferguson@dodgit.com", :birthday => "1980/8/19 00:00:00" | ||
| 652 | Person.create :gender => "male", :first_name => "Edward", :middle_initial => "A", :last_name => "Kerr", :street_address => "50 Thule Drive", :city => "Australia Plains", :state => "SA", :postcode => "5374", :email => "Edward.A.Kerr@trashymail.com", :birthday => "1975/4/8 00:00:00" | ||
| 653 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "S", :last_name => "Winter", :street_address => "17 Myrtle Street", :city => "Wilby", :state => "VIC", :postcode => "3728", :email => "Tom.S.Winter@dodgit.com", :birthday => "1968/4/6 00:00:00" | ||
| 654 | Person.create :gender => "female", :first_name => "Cerys", :middle_initial => "N", :last_name => "Jenkins", :street_address => "39 Purcell Place", :city => "Copmanhurst", :state => "NSW", :postcode => "2460", :email => "Cerys.N.Jenkins@mailinator.com", :birthday => "1957/3/5 00:00:00" | ||
| 655 | Person.create :gender => "male", :first_name => "Henry", :middle_initial => "L", :last_name => "Fisher", :street_address => "19 Redesdale Rd", :city => "Bendigo Forward", :state => "VIC", :postcode => "3551", :email => "Henry.L.Fisher@dodgit.com", :birthday => "1974/1/25 00:00:00" | ||
| 656 | Person.create :gender => "female", :first_name => "Matilda", :middle_initial => "S", :last_name => "Dean", :street_address => "28 Walters Street", :city => "Upotipotpon", :state => "VIC", :postcode => "3673", :email => "Matilda.S.Dean@spambob.com", :birthday => "1983/7/5 00:00:00" | ||
| 657 | Person.create :gender => "male", :first_name => "Leon", :middle_initial => "L", :last_name => "Hussain", :street_address => "78 Albert Street", :city => "Woodhill", :state => "QLD", :postcode => "4285", :email => "Leon.L.Hussain@mailinator.com", :birthday => "1970/3/11 00:00:00" | ||
| 658 | Person.create :gender => "male", :first_name => "Ellis", :middle_initial => "P", :last_name => "Hamilton", :street_address => "18 Cherokee Road", :city => "Daylesford", :state => "VIC", :postcode => "3460", :email => "Ellis.P.Hamilton@pookmail.com", :birthday => "1965/3/7 00:00:00" | ||
| 659 | Person.create :gender => "female", :first_name => "Kayleigh", :middle_initial => "M", :last_name => "Bull", :street_address => "80 Murphy Street", :city => "Cunjardine", :state => "WA", :postcode => "6401", :email => "Kayleigh.M.Bull@spambob.com", :birthday => "1979/7/29 00:00:00" | ||
| 660 | Person.create :gender => "female", :first_name => "Isabella", :middle_initial => "E", :last_name => "Collins", :street_address => "84 English Street", :city => "Long Flat", :state => "SA", :postcode => "5253", :email => "Isabella.E.Collins@mailinator.com", :birthday => "1944/8/5 00:00:00" | ||
| 661 | Person.create :gender => "female", :first_name => "Amber", :middle_initial => "C", :last_name => "Patel", :street_address => "15 Adavale Road", :city => "Six Mile Flat", :state => "NSW", :postcode => "2580", :email => "Amber.C.Patel@pookmail.com", :birthday => "1968/8/9 00:00:00" | ||
| 662 | Person.create :gender => "female", :first_name => "Charlotte", :middle_initial => "L", :last_name => "Sanders", :street_address => "18 Fitzroy Street", :city => "Linton", :state => "VIC", :postcode => "3360", :email => "Charlotte.L.Sanders@mailinator.com", :birthday => "1945/7/20 00:00:00" | ||
| 663 | Person.create :gender => "male", :first_name => "Finley", :middle_initial => "P", :last_name => "Long", :street_address => "20 Frencham Street", :city => "Collendina", :state => "NSW", :postcode => "2646", :email => "Finley.P.Long@dodgit.com", :birthday => "1945/10/7 00:00:00" | ||
| 664 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "V", :last_name => "Marshall", :street_address => "28 Harris Street", :city => "Woodfield", :state => "VIC", :postcode => "3715", :email => "Louie.V.Marshall@dodgit.com", :birthday => "1982/7/6 00:00:00" | ||
| 665 | Person.create :gender => "female", :first_name => "Alexandra", :middle_initial => "K", :last_name => "Thomson", :street_address => "15 Oak Street", :city => "Coraki", :state => "NSW", :postcode => "2471", :email => "Alexandra.K.Thomson@spambob.com", :birthday => "1978/2/28 00:00:00" | ||
| 666 | Person.create :gender => "female", :first_name => "Chloe", :middle_initial => "J", :last_name => "Mills", :street_address => "11 Shadforth Street", :city => "Teal Point", :state => "VIC", :postcode => "3579", :email => "Chloe.J.Mills@trashymail.com", :birthday => "1958/10/4 00:00:00" | ||
| 667 | Person.create :gender => "female", :first_name => "Maya", :middle_initial => "J", :last_name => "Wallis", :street_address => "54 Carlisle Street", :city => "Katamatite", :state => "VIC", :postcode => "3649", :email => "Maya.J.Wallis@spambob.com", :birthday => "1951/11/19 00:00:00" | ||
| 668 | Person.create :gender => "female", :first_name => "Lara", :middle_initial => "N", :last_name => "Ashton", :street_address => "35 Kaesler Road", :city => "Smithville", :state => "SA", :postcode => "5302", :email => "Lara.N.Ashton@trashymail.com", :birthday => "1962/2/18 00:00:00" | ||
| 669 | Person.create :gender => "female", :first_name => "Lauren", :middle_initial => "J", :last_name => "Doherty", :street_address => "30 Wagga Road", :city => "Tolland", :state => "NSW", :postcode => "2650", :email => "Lauren.J.Doherty@dodgit.com", :birthday => "1956/12/17 00:00:00" | ||
| 670 | Person.create :gender => "male", :first_name => "Joe", :middle_initial => "L", :last_name => "Kirk", :street_address => "68 Clifton Street", :city => "Goulburn Weir", :state => "VIC", :postcode => "3608", :email => "Joe.L.Kirk@trashymail.com", :birthday => "1957/2/15 00:00:00" | ||
| 671 | Person.create :gender => "male", :first_name => "Louis", :middle_initial => "A", :last_name => "Davies", :street_address => "98 Paradise Falls Road", :city => "Cheshunt South", :state => "VIC", :postcode => "3678", :email => "Louis.A.Davies@spambob.com", :birthday => "1974/10/17 00:00:00" | ||
| 672 | Person.create :gender => "male", :first_name => "Jordan", :middle_initial => "I", :last_name => "Bishop", :street_address => "48 Boulter Close", :city => "South Innisfail", :state => "QLD", :postcode => "4860", :email => "Jordan.I.Bishop@trashymail.com", :birthday => "1955/5/23 00:00:00" | ||
| 673 | Person.create :gender => "male", :first_name => "Dylan", :middle_initial => "L", :last_name => "Waters", :street_address => "72 Wigley Street", :city => "North Plympton", :state => "SA", :postcode => "5037", :email => "Dylan.L.Waters@trashymail.com", :birthday => "1981/11/21 00:00:00" | ||
| 674 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "S", :last_name => "Hooper", :street_address => "85 Queen Street", :city => "Taylors Point", :state => "NSW", :postcode => "2107", :email => "Jacob.S.Hooper@mailinator.com", :birthday => "1974/5/16 00:00:00" | ||
| 675 | Person.create :gender => "male", :first_name => "Zak", :middle_initial => "S", :last_name => "Donnelly", :street_address => "43 Chapman Avenue", :city => "Yosemite", :state => "NSW", :postcode => "2780", :email => "Zak.S.Donnelly@spambob.com", :birthday => "1967/2/12 00:00:00" | ||
| 676 | Person.create :gender => "male", :first_name => "Anthony", :middle_initial => "A", :last_name => "Bentley", :street_address => "50 Rockhampton Qld", :city => "Rossmoya", :state => "QLD", :postcode => "4702", :email => "Anthony.A.Bentley@trashymail.com", :birthday => "1967/5/22 00:00:00" | ||
| 677 | Person.create :gender => "male", :first_name => "Elliot", :middle_initial => "S", :last_name => "Spencer", :street_address => "83 Weemala Avenue", :city => "Garland", :state => "NSW", :postcode => "2797", :email => "Elliot.S.Spencer@spambob.com", :birthday => "1974/5/27 00:00:00" | ||
| 678 | Person.create :gender => "male", :first_name => "James", :middle_initial => "M", :last_name => "Lowe", :street_address => "66 Garden Place", :city => "Kurraca West", :state => "VIC", :postcode => "3518", :email => "James.M.Lowe@trashymail.com", :birthday => "1985/1/25 00:00:00" | ||
| 679 | Person.create :gender => "male", :first_name => "Charles", :middle_initial => "K", :last_name => "O'ullivan", :street_address => "63 Auricht Road", :city => "Keppoch", :state => "SA", :postcode => "5271", :email => "Charles.K.O'ullivan@pookmail.com", :birthday => "1984/11/11 00:00:00" | ||
| 680 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "A", :last_name => "Birch", :street_address => "49 Weemala Avenue", :city => "Koorawatha", :state => "NSW", :postcode => "2807", :email => "Christopher.A.Birch@spambob.com", :birthday => "1979/9/16 00:00:00" | ||
| 681 | Person.create :gender => "male", :first_name => "Alfie", :middle_initial => "C", :last_name => "Heath", :street_address => "91 Clifton Street", :city => "Wahring", :state => "VIC", :postcode => "3608", :email => "Alfie.C.Heath@pookmail.com", :birthday => "1957/10/11 00:00:00" | ||
| 682 | Person.create :gender => "female", :first_name => "Alisha", :middle_initial => "J", :last_name => "Dixon", :street_address => "31 Raglan Street", :city => "Boyneside", :state => "QLD", :postcode => "4610", :email => "Alisha.J.Dixon@dodgit.com", :birthday => "1974/7/14 00:00:00" | ||
| 683 | Person.create :gender => "male", :first_name => "Bailey", :middle_initial => "M", :last_name => "Simpson", :street_address => "13 Halsey Road", :city => "Goolwa", :state => "SA", :postcode => "5214", :email => "Bailey.M.Simpson@trashymail.com", :birthday => "1949/5/8 00:00:00" | ||
| 684 | Person.create :gender => "male", :first_name => "Joshua", :middle_initial => "A", :last_name => "Hope", :street_address => "43 Springhill Bottom Road", :city => "Cluan", :state => "TAS", :postcode => "7303", :email => "Joshua.A.Hope@trashymail.com", :birthday => "1955/7/11 00:00:00" | ||
| 685 | Person.create :gender => "male", :first_name => "Kian", :middle_initial => "L", :last_name => "O'onnor", :street_address => "64 Loris Way", :city => "Yilliminning", :state => "WA", :postcode => "6312", :email => "Kian.L.O'onnor@spambob.com", :birthday => "1974/9/9 00:00:00" | ||
| 686 | Person.create :gender => "male", :first_name => "John", :middle_initial => "H", :last_name => "Collins", :street_address => "39 Peterho Boulevard", :city => "Buckland Park", :state => "SA", :postcode => "5120", :email => "John.H.Collins@dodgit.com", :birthday => "1962/12/2 00:00:00" | ||
| 687 | Person.create :gender => "male", :first_name => "George", :middle_initial => "E", :last_name => "O'rien", :street_address => "48 Woolnough Road", :city => "Waterfall Gully", :state => "SA", :postcode => "5066", :email => "George.E.O'rien@mailinator.com", :birthday => "1973/8/27 00:00:00" | ||
| 688 | Person.create :gender => "male", :first_name => "Leon", :middle_initial => "L", :last_name => "Holmes", :street_address => "53 Bayview Close", :city => "Tieri", :state => "QLD", :postcode => "4709", :email => "Leon.L.Holmes@trashymail.com", :birthday => "1976/9/25 00:00:00" | ||
| 689 | Person.create :gender => "female", :first_name => "Eloise", :middle_initial => "M", :last_name => "King", :street_address => "75 Southwell Crescent", :city => "Charley Creek", :state => "WA", :postcode => "6239", :email => "Eloise.M.King@trashymail.com", :birthday => "1950/3/19 00:00:00" | ||
| 690 | Person.create :gender => "male", :first_name => "Jude", :middle_initial => "E", :last_name => "Iqbal", :street_address => "36 Bailey Street", :city => "Yarpturk", :state => "VIC", :postcode => "3283", :email => "Jude.E.Iqbal@dodgit.com", :birthday => "1970/7/24 00:00:00" | ||
| 691 | Person.create :gender => "male", :first_name => "Michael", :middle_initial => "A", :last_name => "Stephens", :street_address => "78 Old Tenterfield Road", :city => "Mookima Wybra", :state => "NSW", :postcode => "2469", :email => "Michael.A.Stephens@mailinator.com", :birthday => "1955/7/9 00:00:00" | ||
| 692 | Person.create :gender => "female", :first_name => "Chelsea", :middle_initial => "S", :last_name => "Hilton", :street_address => "58 Chatsworth Drive", :city => "St James", :state => "WA", :postcode => "6102", :email => "Chelsea.S.Hilton@mailinator.com", :birthday => "1967/10/12 00:00:00" | ||
| 693 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "A", :last_name => "Cunningham", :street_address => "6 Southwell Crescent", :city => "Withers", :state => "WA", :postcode => "6230", :email => "Sam.A.Cunningham@trashymail.com", :birthday => "1973/4/9 00:00:00" | ||
| 694 | Person.create :gender => "male", :first_name => "Spencer", :middle_initial => "E", :last_name => "Thomson", :street_address => "16 Barker Street", :city => "Broomehill", :state => "WA", :postcode => "6318", :email => "Spencer.E.Thomson@trashymail.com", :birthday => "1977/3/15 00:00:00" | ||
| 695 | Person.create :gender => "female", :first_name => "Katie", :middle_initial => "R", :last_name => "Dennis", :street_address => "57 Healy Road", :city => "Queenwood", :state => "WA", :postcode => "6239", :email => "Katie.R.Dennis@trashymail.com", :birthday => "1942/3/13 00:00:00" | ||
| 696 | Person.create :gender => "female", :first_name => "Matilda", :middle_initial => "S", :last_name => "Parry", :street_address => "91 Begley Street", :city => "Tarzali", :state => "QLD", :postcode => "4885", :email => "Matilda.S.Parry@trashymail.com", :birthday => "1985/2/4 00:00:00" | ||
| 697 | Person.create :gender => "male", :first_name => "Lewis", :middle_initial => "J", :last_name => "Gregory", :street_address => "22 Gaffney Street", :city => "Lara", :state => "VIC", :postcode => "3212", :email => "Lewis.J.Gregory@spambob.com", :birthday => "1968/4/30 00:00:00" | ||
| 698 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "B", :last_name => "McCarthy", :street_address => "35 Albert Street", :city => "Christmas Creek", :state => "QLD", :postcode => "4285", :email => "Jake.B.McCarthy@dodgit.com", :birthday => "1960/1/6 00:00:00" | ||
| 699 | Person.create :gender => "male", :first_name => "Leon", :middle_initial => "F", :last_name => "Rees", :street_address => "79 Ashton Road", :city => "Pantapin", :state => "WA", :postcode => "6384", :email => "Leon.F.Rees@trashymail.com", :birthday => "1960/12/3 00:00:00" | ||
| 700 | Person.create :gender => "female", :first_name => "Maya", :middle_initial => "P", :last_name => "Wright", :street_address => "50 Armstrong Street", :city => "Mincha West", :state => "VIC", :postcode => "3568", :email => "Maya.P.Wright@mailinator.com", :birthday => "1962/5/31 00:00:00" | ||
| 701 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "C", :last_name => "Hargreaves", :street_address => "97 Elizabeth Street", :city => "Widgee", :state => "QLD", :postcode => "4570", :email => "Francesca.C.Hargreaves@dodgit.com", :birthday => "1940/10/22 00:00:00" | ||
| 702 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "C", :last_name => "Norton", :street_address => "7 Elgin Street", :city => "Windella", :state => "NSW", :postcode => "2320", :email => "Zachary.C.Norton@dodgit.com", :birthday => "1954/9/9 00:00:00" | ||
| 703 | Person.create :gender => "female", :first_name => "Matilda", :middle_initial => "A", :last_name => "Weston", :street_address => "32 Reynolds Road", :city => "Banks Pocket", :state => "QLD", :postcode => "4570", :email => "Matilda.A.Weston@dodgit.com", :birthday => "1977/5/25 00:00:00" | ||
| 704 | Person.create :gender => "male", :first_name => "Morgan", :middle_initial => "I", :last_name => "McKenzie", :street_address => "72 Shamrock Avenue", :city => "Tomakin", :state => "NSW", :postcode => "2537", :email => "Morgan.I.McKenzie@dodgit.com", :birthday => "1963/3/13 00:00:00" | ||
| 705 | Person.create :gender => "male", :first_name => "Bradley", :middle_initial => "A", :last_name => "Akhtar", :street_address => "85 Argyle Street", :city => "Rookhurst", :state => "NSW", :postcode => "2422", :email => "Bradley.A.Akhtar@pookmail.com", :birthday => "1941/4/3 00:00:00" | ||
| 706 | Person.create :gender => "female", :first_name => "Laura", :middle_initial => "A", :last_name => "Turner", :street_address => "18 Dora Creek", :city => "Woodlawn", :state => "NSW", :postcode => "2480", :email => "Laura.A.Turner@pookmail.com", :birthday => "1962/9/30 00:00:00" | ||
| 707 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "L", :last_name => "Stephenson", :street_address => "92 Scenic Road", :city => "Berridale", :state => "NSW", :postcode => "2628", :email => "Jake.L.Stephenson@trashymail.com", :birthday => "1943/9/5 00:00:00" | ||
| 708 | Person.create :gender => "male", :first_name => "Alfie", :middle_initial => "C", :last_name => "Cole", :street_address => "33 Gadd Avenue", :city => "Snowtown", :state => "SA", :postcode => "5520", :email => "Alfie.C.Cole@dodgit.com", :birthday => "1958/10/11 00:00:00" | ||
| 709 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "G", :last_name => "Joyce", :street_address => "85 Hillsdale Road", :city => "Brovinia", :state => "QLD", :postcode => "4626", :email => "Ethan.G.Joyce@dodgit.com", :birthday => "1958/3/26 00:00:00" | ||
| 710 | Person.create :gender => "female", :first_name => "Ellie", :middle_initial => "M", :last_name => "Quinn", :street_address => "17 Springhill Bottom Road", :city => "Paradise", :state => "TAS", :postcode => "7306", :email => "Ellie.M.Quinn@trashymail.com", :birthday => "1968/12/21 00:00:00" | ||
| 711 | Person.create :gender => "female", :first_name => "Gracie", :middle_initial => "I", :last_name => "Davies", :street_address => "67 Carlisle Street", :city => "Tarcombe", :state => "VIC", :postcode => "3666", :email => "Gracie.I.Davies@spambob.com", :birthday => "1961/12/23 00:00:00" | ||
| 712 | Person.create :gender => "male", :first_name => "Kieran", :middle_initial => "C", :last_name => "Field", :street_address => "29 Avondale Drive", :city => "Windang", :state => "NSW", :postcode => "2528", :email => "Kieran.C.Field@mailinator.com", :birthday => "1950/7/4 00:00:00" | ||
| 713 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "J", :last_name => "Harvey", :street_address => "61 Alfred Street", :city => "Esperance", :state => "WA", :postcode => "6450", :email => "Owen.J.Harvey@mailinator.com", :birthday => "1952/11/21 00:00:00" | ||
| 714 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "J", :last_name => "Young", :street_address => "36 Tooraweenah Road", :city => "Nanardine", :state => "NSW", :postcode => "2870", :email => "Tegan.J.Young@spambob.com", :birthday => "1953/8/15 00:00:00" | ||
| 715 | Person.create :gender => "female", :first_name => "Gracie", :middle_initial => "T", :last_name => "Adams", :street_address => "67 Southwell Crescent", :city => "Waterloo", :state => "WA", :postcode => "6228", :email => "Gracie.T.Adams@pookmail.com", :birthday => "1950/6/6 00:00:00" | ||
| 716 | Person.create :gender => "male", :first_name => "Archie", :middle_initial => "M", :last_name => "Whitehouse", :street_address => "85 Maintongoon Road", :city => "Moe South", :state => "VIC", :postcode => "3825", :email => "Archie.M.Whitehouse@dodgit.com", :birthday => "1961/2/22 00:00:00" | ||
| 717 | Person.create :gender => "female", :first_name => "Libby", :middle_initial => "D", :last_name => "Marsh", :street_address => "81 Barker Street", :city => "Kenmare", :state => "WA", :postcode => "6316", :email => "Libby.D.Marsh@pookmail.com", :birthday => "1980/9/17 00:00:00" | ||
| 718 | Person.create :gender => "male", :first_name => "Harry", :middle_initial => "E", :last_name => "Hargreaves", :street_address => "79 Patton Street", :city => "Warranwood", :state => "VIC", :postcode => "3134", :email => "Harry.E.Hargreaves@trashymail.com", :birthday => "1959/12/24 00:00:00" | ||
| 719 | Person.create :gender => "female", :first_name => "Madison", :middle_initial => "J", :last_name => "Gilbert", :street_address => "68 Rose Street", :city => "Kallista", :state => "VIC", :postcode => "3791", :email => "Madison.J.Gilbert@dodgit.com", :birthday => "1978/10/11 00:00:00" | ||
| 720 | Person.create :gender => "male", :first_name => "Henry", :middle_initial => "S", :last_name => "Nicholson", :street_address => "97 Parkes Road", :city => "Ardeer", :state => "VIC", :postcode => "3022", :email => "Henry.S.Nicholson@mailinator.com", :birthday => "1953/10/9 00:00:00" | ||
| 721 | Person.create :gender => "female", :first_name => "Samantha", :middle_initial => "J", :last_name => "Warren", :street_address => "63 McGregor Street", :city => "Bonython", :state => "ACT", :postcode => "2905", :email => "Samantha.J.Warren@spambob.com", :birthday => "1948/8/10 00:00:00" | ||
| 722 | Person.create :gender => "male", :first_name => "Noah", :middle_initial => "R", :last_name => "Palmer", :street_address => "42 Sydney Road", :city => "Maitland Bar", :state => "NSW", :postcode => "2850", :email => "Noah.R.Palmer@mailinator.com", :birthday => "1941/8/22 00:00:00" | ||
| 723 | Person.create :gender => "male", :first_name => "Morgan", :middle_initial => "N", :last_name => "Bird", :street_address => "34 Taylor Street", :city => "Bunbartha", :state => "VIC", :postcode => "3634", :email => "Morgan.N.Bird@dodgit.com", :birthday => "1980/6/29 00:00:00" | ||
| 724 | Person.create :gender => "female", :first_name => "Charlotte", :middle_initial => "S", :last_name => "Watts", :street_address => "9 Queen Street", :city => "Collaroy Beach", :state => "NSW", :postcode => "2097", :email => "Charlotte.S.Watts@trashymail.com", :birthday => "1964/9/7 00:00:00" | ||
| 725 | Person.create :gender => "female", :first_name => "Libby", :middle_initial => "S", :last_name => "Carter", :street_address => "60 Woerdens Road", :city => "Raymond Terrace", :state => "NSW", :postcode => "2324", :email => "Libby.S.Carter@mailinator.com", :birthday => "1951/6/26 00:00:00" | ||
| 726 | Person.create :gender => "female", :first_name => "Jessica", :middle_initial => "E", :last_name => "Begum", :street_address => "77 Mnimbah Road", :city => "Gresford", :state => "NSW", :postcode => "2311", :email => "Jessica.E.Begum@pookmail.com", :birthday => "1981/12/28 00:00:00" | ||
| 727 | Person.create :gender => "male", :first_name => "Sebastian", :middle_initial => "H", :last_name => "Storey", :street_address => "45 Edmundsons Road", :city => "Lamplough", :state => "VIC", :postcode => "3352", :email => "Sebastian.H.Storey@mailinator.com", :birthday => "1956/1/6 00:00:00" | ||
| 728 | Person.create :gender => "male", :first_name => "Kyle", :middle_initial => "S", :last_name => "Morris", :street_address => "88 Girvan Grove", :city => "Eaglehawk North", :state => "VIC", :postcode => "3556", :email => "Kyle.S.Morris@dodgit.com", :birthday => "1944/10/18 00:00:00" | ||
| 729 | Person.create :gender => "male", :first_name => "Finlay", :middle_initial => "G", :last_name => "Lewis", :street_address => "38 Panorama Road", :city => "Kingswood", :state => "NSW", :postcode => "2340", :email => "Finlay.G.Lewis@pookmail.com", :birthday => "1977/5/31 00:00:00" | ||
| 730 | Person.create :gender => "female", :first_name => "Lydia", :middle_initial => "H", :last_name => "Fitzgerald", :street_address => "49 Bungana Drive", :city => "Polish Hill River", :state => "SA", :postcode => "5453", :email => "Lydia.H.Fitzgerald@trashymail.com", :birthday => "1943/6/27 00:00:00" | ||
| 731 | Person.create :gender => "female", :first_name => "Caitlin", :middle_initial => "B", :last_name => "Atkins", :street_address => "4 Saggers Road", :city => "Forrestania", :state => "WA", :postcode => "6359", :email => "Caitlin.B.Atkins@dodgit.com", :birthday => "1982/2/15 00:00:00" | ||
| 732 | Person.create :gender => "male", :first_name => "Billy", :middle_initial => "S", :last_name => "Page", :street_address => "25 Sunraysia Road", :city => "Cardigan", :state => "VIC", :postcode => "3352", :email => "Billy.S.Page@trashymail.com", :birthday => "1983/11/4 00:00:00" | ||
| 733 | Person.create :gender => "female", :first_name => "Charlie", :middle_initial => "E", :last_name => "Khan", :street_address => "72 Dalgarno Street", :city => "Nowley", :state => "NSW", :postcode => "2386", :email => "Charlie.E.Khan@dodgit.com", :birthday => "1951/12/12 00:00:00" | ||
| 734 | Person.create :gender => "male", :first_name => "Owen", :middle_initial => "H", :last_name => "Ali", :street_address => "90 Fitzroy Street", :city => "Ballarat East", :state => "VIC", :postcode => "3350", :email => "Owen.H.Ali@spambob.com", :birthday => "1958/9/5 00:00:00" | ||
| 735 | Person.create :gender => "female", :first_name => "Mia", :middle_initial => "A", :last_name => "Gould", :street_address => "33 Thule Drive", :city => "Julia", :state => "SA", :postcode => "5374", :email => "Mia.A.Gould@spambob.com", :birthday => "1959/10/7 00:00:00" | ||
| 736 | Person.create :gender => "male", :first_name => "Joe", :middle_initial => "P", :last_name => "Miah", :street_address => "83 South Street", :city => "Tinderbox", :state => "TAS", :postcode => "7054", :email => "Joe.P.Miah@spambob.com", :birthday => "1940/8/17 00:00:00" | ||
| 737 | Person.create :gender => "male", :first_name => "Jamie", :middle_initial => "S", :last_name => "Mills", :street_address => "18 Chapman Avenue", :city => "Mozart", :state => "NSW", :postcode => "2787", :email => "Jamie.S.Mills@mailinator.com", :birthday => "1980/6/10 00:00:00" | ||
| 738 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "A", :last_name => "Carter", :street_address => "35 Larissa Court", :city => "Merrinee", :state => "VIC", :postcode => "3496", :email => "Louie.A.Carter@pookmail.com", :birthday => "1971/9/5 00:00:00" | ||
| 739 | Person.create :gender => "female", :first_name => "Grace", :middle_initial => "M", :last_name => "Wade", :street_address => "89 Black Range Road", :city => "New Buildings", :state => "NSW", :postcode => "2550", :email => "Grace.M.Wade@spambob.com", :birthday => "1945/2/9 00:00:00" | ||
| 740 | Person.create :gender => "female", :first_name => "Sarah", :middle_initial => "Z", :last_name => "Robson", :street_address => "29 Glenpark Road", :city => "North Boambee Valley", :state => "NSW", :postcode => "2450", :email => "Sarah.Z.Robson@pookmail.com", :birthday => "1957/10/2 00:00:00" | ||
| 741 | Person.create :gender => "female", :first_name => "Abbie", :middle_initial => "J", :last_name => "Dobson", :street_address => "56 Porana Place", :city => "Tenindewa", :state => "WA", :postcode => "6632", :email => "Abbie.J.Dobson@pookmail.com", :birthday => "1952/1/12 00:00:00" | ||
| 742 | Person.create :gender => "male", :first_name => "Michael", :middle_initial => "S", :last_name => "O'ullivan", :street_address => "17 Jones Road", :city => "Dutton Park", :state => "QLD", :postcode => "4102", :email => "Michael.S.O'ullivan@pookmail.com", :birthday => "1959/7/22 00:00:00" | ||
| 743 | Person.create :gender => "male", :first_name => "Oliver", :middle_initial => "S", :last_name => "Johnston", :street_address => "69 Healy Road", :city => "Greenbushes", :state => "WA", :postcode => "6254", :email => "Oliver.S.Johnston@dodgit.com", :birthday => "1975/8/18 00:00:00" | ||
| 744 | Person.create :gender => "female", :first_name => "Amber", :middle_initial => "A", :last_name => "Bull", :street_address => "86 Wilson Street", :city => "Towaninny South", :state => "VIC", :postcode => "3527", :email => "Amber.A.Bull@dodgit.com", :birthday => "1941/1/26 00:00:00" | ||
| 745 | Person.create :gender => "female", :first_name => "Harriet", :middle_initial => "T", :last_name => "Ryan", :street_address => "25 Carlisle Street", :city => "Mangalore", :state => "VIC", :postcode => "3663", :email => "Harriet.T.Ryan@mailinator.com", :birthday => "1950/11/11 00:00:00" | ||
| 746 | Person.create :gender => "female", :first_name => "Samantha", :middle_initial => "C", :last_name => "Hooper", :street_address => "21 Aquatic Road", :city => "Dumaresq Island", :state => "NSW", :postcode => "2430", :email => "Samantha.C.Hooper@dodgit.com", :birthday => "1974/7/9 00:00:00" | ||
| 747 | Person.create :gender => "male", :first_name => "Mohammad", :middle_initial => "S", :last_name => "Webb", :street_address => "17 Aquatic Road", :city => "Taree West", :state => "NSW", :postcode => "2430", :email => "Mohammad.S.Webb@pookmail.com", :birthday => "1962/7/21 00:00:00" | ||
| 748 | Person.create :gender => "male", :first_name => "Billy", :middle_initial => "D", :last_name => "Robertson", :street_address => "32 Delan Road", :city => "Mungy", :state => "QLD", :postcode => "4671", :email => "Billy.D.Robertson@trashymail.com", :birthday => "1940/4/20 00:00:00" | ||
| 749 | Person.create :gender => "female", :first_name => "Aimee", :middle_initial => "T", :last_name => "Williamson", :street_address => "53 Hunter Street", :city => "Drayton North", :state => "QLD", :postcode => "4350", :email => "Aimee.T.Williamson@dodgit.com", :birthday => "1960/10/8 00:00:00" | ||
| 750 | Person.create :gender => "male", :first_name => "Max", :middle_initial => "A", :last_name => "Tomlinson", :street_address => "99 Bellion Drive", :city => "Northcliffe", :state => "WA", :postcode => "6262", :email => "Max.A.Tomlinson@spambob.com", :birthday => "1947/7/11 00:00:00" | ||
| 751 | Person.create :gender => "male", :first_name => "Reece", :middle_initial => "C", :last_name => "Ryan", :street_address => "77 Edgewater Close", :city => "Bream Beach", :state => "NSW", :postcode => "2540", :email => "Reece.C.Ryan@mailinator.com", :birthday => "1960/12/9 00:00:00" | ||
| 752 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "S", :last_name => "Cameron", :street_address => "46 Cherokee Road", :city => "Bradford", :state => "VIC", :postcode => "3463", :email => "Jake.S.Cameron@spambob.com", :birthday => "1980/1/21 00:00:00" | ||
| 753 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "H", :last_name => "Owens", :street_address => "24 Sunset Drive", :city => "Maneroo", :state => "QLD", :postcode => "4730", :email => "Christopher.H.Owens@spambob.com", :birthday => "1984/10/6 00:00:00" | ||
| 754 | Person.create :gender => "male", :first_name => "Elliot", :middle_initial => "H", :last_name => "Pratt", :street_address => "77 Boughtman Street", :city => "Oakleigh South", :state => "VIC", :postcode => "3167", :email => "Elliot.H.Pratt@mailinator.com", :birthday => "1940/1/28 00:00:00" | ||
| 755 | Person.create :gender => "female", :first_name => "Leah", :middle_initial => "W", :last_name => "Pearson", :street_address => "67 Larissa Court", :city => "Linga", :state => "VIC", :postcode => "3509", :email => "Leah.W.Pearson@trashymail.com", :birthday => "1947/3/21 00:00:00" | ||
| 756 | Person.create :gender => "male", :first_name => "Sebastian", :middle_initial => "E", :last_name => "Poole", :street_address => "96 Amiens Road", :city => "Carcalgong", :state => "NSW", :postcode => "2850", :email => "Sebastian.E.Poole@spambob.com", :birthday => "1963/11/21 00:00:00" | ||
| 757 | Person.create :gender => "female", :first_name => "Brooke", :middle_initial => "Z", :last_name => "Byrne", :street_address => "30 Queen Street", :city => "Oxford Falls", :state => "NSW", :postcode => "2100", :email => "Brooke.Z.Byrne@pookmail.com", :birthday => "1966/9/16 00:00:00" | ||
| 758 | Person.create :gender => "female", :first_name => "Lily", :middle_initial => "C", :last_name => "Rowe", :street_address => "46 Redesdale Rd", :city => "Painswick", :state => "VIC", :postcode => "3551", :email => "Lily.C.Rowe@spambob.com", :birthday => "1966/10/15 00:00:00" | ||
| 759 | Person.create :gender => "female", :first_name => "Ella", :middle_initial => "S", :last_name => "Cole", :street_address => "82 Yangan Drive", :city => "Tintinhull", :state => "NSW", :postcode => "2352", :email => "Ella.S.Cole@pookmail.com", :birthday => "1978/7/19 00:00:00" | ||
| 760 | Person.create :gender => "female", :first_name => "Nicole", :middle_initial => "J", :last_name => "Bray", :street_address => "85 Wilson Street", :city => "Dumosa", :state => "VIC", :postcode => "3527", :email => "Nicole.J.Bray@pookmail.com", :birthday => "1955/8/15 00:00:00" | ||
| 761 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "A", :last_name => "Hurst", :street_address => "51 Maintongoon Road", :city => "Toorongo", :state => "VIC", :postcode => "3833", :email => "Zachary.A.Hurst@trashymail.com", :birthday => "1985/7/16 00:00:00" | ||
| 762 | Person.create :gender => "female", :first_name => "Melissa", :middle_initial => "S", :last_name => "Miles", :street_address => "29 Grandis Road", :city => "Temagog", :state => "NSW", :postcode => "2440", :email => "Melissa.S.Miles@pookmail.com", :birthday => "1973/4/15 00:00:00" | ||
| 763 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "G", :last_name => "Nixon", :street_address => "67 Mt Berryman Road", :city => "Ringwood", :state => "QLD", :postcode => "4343", :email => "Christopher.G.Nixon@spambob.com", :birthday => "1965/3/14 00:00:00" | ||
| 764 | Person.create :gender => "male", :first_name => "John", :middle_initial => "A", :last_name => "Marsh", :street_address => "88 Mendooran Road", :city => "Delroy Gardens", :state => "NSW", :postcode => "2830", :email => "John.A.Marsh@dodgit.com", :birthday => "1970/5/25 00:00:00" | ||
| 765 | Person.create :gender => "female", :first_name => "Danielle", :middle_initial => "L", :last_name => "Nolan", :street_address => "37 McLeans Road", :city => "Mungungo", :state => "QLD", :postcode => "4630", :email => "Danielle.L.Nolan@trashymail.com", :birthday => "1974/9/7 00:00:00" | ||
| 766 | Person.create :gender => "female", :first_name => "Maisie", :middle_initial => "J", :last_name => "Davison", :street_address => "71 Kerma Crescent", :city => "Bowenfels", :state => "NSW", :postcode => "2790", :email => "Maisie.J.Davison@dodgit.com", :birthday => "1962/3/15 00:00:00" | ||
| 767 | Person.create :gender => "male", :first_name => "Oliver", :middle_initial => "E", :last_name => "Fuller", :street_address => "40 Gaffney Street", :city => "Belvedere Park", :state => "VIC", :postcode => "3198", :email => "Oliver.E.Fuller@spambob.com", :birthday => "1941/10/15 00:00:00" | ||
| 768 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "C", :last_name => "Watson", :street_address => "2 Wilson Street", :city => "Lalbert", :state => "VIC", :postcode => "3542", :email => "Sam.C.Watson@dodgit.com", :birthday => "1952/4/11 00:00:00" | ||
| 769 | Person.create :gender => "female", :first_name => "Jodie", :middle_initial => "E", :last_name => "Faulkner", :street_address => "87 Auricht Road", :city => "Monbulla", :state => "SA", :postcode => "5277", :email => "Jodie.E.Faulkner@mailinator.com", :birthday => "1974/10/2 00:00:00" | ||
| 770 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "S", :last_name => "Parsons", :street_address => "32 Purcell Place", :city => "Grafton West", :state => "NSW", :postcode => "2460", :email => "Francesca.S.Parsons@spambob.com", :birthday => "1966/1/5 00:00:00" | ||
| 771 | Person.create :gender => "male", :first_name => "Alexander", :middle_initial => "S", :last_name => "Hooper", :street_address => "51 Davenport Street", :city => "Ournie", :state => "NSW", :postcode => "2640", :email => "Alexander.S.Hooper@mailinator.com", :birthday => "1969/6/17 00:00:00" | ||
| 772 | Person.create :gender => "male", :first_name => "Lucas", :middle_initial => "M", :last_name => "Berry", :street_address => "59 Loris Way", :city => "Pumphreys Bridge", :state => "WA", :postcode => "6308", :email => "Lucas.M.Berry@pookmail.com", :birthday => "1940/2/19 00:00:00" | ||
| 773 | Person.create :gender => "male", :first_name => "Scott", :middle_initial => "D", :last_name => "Watson", :street_address => "96 Henry Moss Court", :city => "Lewiston", :state => "SA", :postcode => "5501", :email => "Scott.D.Watson@spambob.com", :birthday => "1952/7/8 00:00:00" | ||
| 774 | Person.create :gender => "female", :first_name => "Alisha", :middle_initial => "T", :last_name => "Perkins", :street_address => "10 Shannon Court", :city => "Erskine", :state => "SA", :postcode => "5422", :email => "Alisha.T.Perkins@trashymail.com", :birthday => "1975/10/11 00:00:00" | ||
| 775 | Person.create :gender => "female", :first_name => "Cerys", :middle_initial => "R", :last_name => "Thomson", :street_address => "16 Dabinett Road", :city => "Cowirra", :state => "SA", :postcode => "5238", :email => "Cerys.R.Thomson@pookmail.com", :birthday => "1970/8/18 00:00:00" | ||
| 776 | Person.create :gender => "male", :first_name => "David", :middle_initial => "I", :last_name => "Campbell", :street_address => "73 Frouds Road", :city => "Hastings", :state => "VIC", :postcode => "3915", :email => "David.I.Campbell@spambob.com", :birthday => "1973/7/22 00:00:00" | ||
| 777 | Person.create :gender => "female", :first_name => "Hannah", :middle_initial => "D", :last_name => "Norton", :street_address => "79 Gadd Avenue", :city => "Thrington", :state => "SA", :postcode => "5552", :email => "Hannah.D.Norton@mailinator.com", :birthday => "1966/8/3 00:00:00" | ||
| 778 | Person.create :gender => "male", :first_name => "Luca", :middle_initial => "R", :last_name => "Iqbal", :street_address => "38 Goldfields Road", :city => "Cutella", :state => "QLD", :postcode => "4352", :email => "Luca.R.Iqbal@trashymail.com", :birthday => "1942/8/12 00:00:00" | ||
| 779 | Person.create :gender => "male", :first_name => "Nicholas", :middle_initial => "A", :last_name => "Burrows", :street_address => "86 Devon Street", :city => "Marleston", :state => "SA", :postcode => "5033", :email => "Nicholas.A.Burrows@pookmail.com", :birthday => "1957/7/2 00:00:00" | ||
| 780 | Person.create :gender => "male", :first_name => "Tyler", :middle_initial => "T", :last_name => "Norman", :street_address => "84 Carolina Park Road", :city => "Forresters Beach", :state => "NSW", :postcode => "2260", :email => "Tyler.T.Norman@spambob.com", :birthday => "1984/7/17 00:00:00" | ||
| 781 | Person.create :gender => "male", :first_name => "Christopher", :middle_initial => "S", :last_name => "Perkins", :street_address => "90 Woerdens Road", :city => "Seaham", :state => "NSW", :postcode => "2324", :email => "Christopher.S.Perkins@pookmail.com", :birthday => "1965/3/28 00:00:00" | ||
| 782 | Person.create :gender => "male", :first_name => "Harvey", :middle_initial => "G", :last_name => "Scott", :street_address => "36 Sinclair Street", :city => "Alford", :state => "SA", :postcode => "5555", :email => "Harvey.G.Scott@pookmail.com", :birthday => "1950/1/5 00:00:00" | ||
| 783 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "H", :last_name => "Jordan", :street_address => "40 Rose Street", :city => "Guys Hill", :state => "VIC", :postcode => "3807", :email => "Isabelle.H.Jordan@mailinator.com", :birthday => "1948/7/14 00:00:00" | ||
| 784 | Person.create :gender => "male", :first_name => "Muhammad", :middle_initial => "L", :last_name => "Smart", :street_address => "93 Denison Road", :city => "Crib Point", :state => "VIC", :postcode => "3919", :email => "Muhammad.L.Smart@pookmail.com", :birthday => "1948/8/25 00:00:00" | ||
| 785 | Person.create :gender => "male", :first_name => "Zachary", :middle_initial => "K", :last_name => "Sheppard", :street_address => "5 Alfred Street", :city => "Salmon Gums", :state => "WA", :postcode => "6445", :email => "Zachary.K.Sheppard@pookmail.com", :birthday => "1985/10/27 00:00:00" | ||
| 786 | Person.create :gender => "male", :first_name => "Joel", :middle_initial => "J", :last_name => "Chamberlain", :street_address => "8 English Street", :city => "Burdett", :state => "SA", :postcode => "5253", :email => "Joel.J.Chamberlain@dodgit.com", :birthday => "1965/11/27 00:00:00" | ||
| 787 | Person.create :gender => "female", :first_name => "Jennifer", :middle_initial => "J", :last_name => "Rice", :street_address => "88 Benny Street", :city => "Erriba", :state => "TAS", :postcode => "7310", :email => "Jennifer.J.Rice@mailinator.com", :birthday => "1964/1/15 00:00:00" | ||
| 788 | Person.create :gender => "female", :first_name => "Scarlett", :middle_initial => "A", :last_name => "Ward", :street_address => "49 Chester Street", :city => "Cobaki", :state => "NSW", :postcode => "2486", :email => "Scarlett.A.Ward@dodgit.com", :birthday => "1969/2/16 00:00:00" | ||
| 789 | Person.create :gender => "male", :first_name => "Dominic", :middle_initial => "S", :last_name => "Higgins", :street_address => "7 Bailey Street", :city => "Warrabkook", :state => "VIC", :postcode => "3286", :email => "Dominic.S.Higgins@mailinator.com", :birthday => "1953/1/21 00:00:00" | ||
| 790 | Person.create :gender => "male", :first_name => "Alfie", :middle_initial => "J", :last_name => "Matthews", :street_address => "53 Derry Street", :city => "Strathpine", :state => "QLD", :postcode => "4500", :email => "Alfie.J.Matthews@spambob.com", :birthday => "1949/10/13 00:00:00" | ||
| 791 | Person.create :gender => "female", :first_name => "Jasmine", :middle_initial => "A", :last_name => "Morrison", :street_address => "71 Tanner Street", :city => "Barrow Creek", :state => "NT", :postcode => "0872", :email => "Jasmine.A.Morrison@dodgit.com", :birthday => "1979/3/14 00:00:00" | ||
| 792 | Person.create :gender => "male", :first_name => "Hayden", :middle_initial => "A", :last_name => "Farmer", :street_address => "27 Banksia Street", :city => "Useless Loop", :state => "WA", :postcode => "6537", :email => "Hayden.A.Farmer@pookmail.com", :birthday => "1974/5/12 00:00:00" | ||
| 793 | Person.create :gender => "female", :first_name => "Sienna", :middle_initial => "S", :last_name => "Dyer", :street_address => "5 Thule Drive", :city => "Templers", :state => "SA", :postcode => "5371", :email => "Sienna.S.Dyer@trashymail.com", :birthday => "1954/5/31 00:00:00" | ||
| 794 | Person.create :gender => "male", :first_name => "Louis", :middle_initial => "R", :last_name => "Turnbull", :street_address => "27 Moruya Street", :city => "Cobargo", :state => "NSW", :postcode => "2550", :email => "Louis.R.Turnbull@spambob.com", :birthday => "1958/4/10 00:00:00" | ||
| 795 | Person.create :gender => "female", :first_name => "Elise", :middle_initial => "D", :last_name => "Alexander", :street_address => "25 Normans Road", :city => "Patyah", :state => "VIC", :postcode => "3318", :email => "Elise.D.Alexander@pookmail.com", :birthday => "1960/4/29 00:00:00" | ||
| 796 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "N", :last_name => "Evans", :street_address => "48 Denison Road", :city => "Silverleaves", :state => "VIC", :postcode => "3922", :email => "Jake.N.Evans@trashymail.com", :birthday => "1972/1/21 00:00:00" | ||
| 797 | Person.create :gender => "male", :first_name => "Josh", :middle_initial => "E", :last_name => "Bentley", :street_address => "32 Balonne Street", :city => "Gum Scrub", :state => "NSW", :postcode => "2441", :email => "Josh.E.Bentley@pookmail.com", :birthday => "1969/8/9 00:00:00" | ||
| 798 | Person.create :gender => "male", :first_name => "Leo", :middle_initial => "A", :last_name => "Dale", :street_address => "10 Boorie Road", :city => "Gordonbrook", :state => "QLD", :postcode => "4610", :email => "Leo.A.Dale@pookmail.com", :birthday => "1956/3/5 00:00:00" | ||
| 799 | Person.create :gender => "male", :first_name => "Alexander", :middle_initial => "G", :last_name => "Gallagher", :street_address => "89 Raglan Street", :city => "Crownthorpe", :state => "QLD", :postcode => "4605", :email => "Alexander.G.Gallagher@spambob.com", :birthday => "1958/1/13 00:00:00" | ||
| 800 | Person.create :gender => "male", :first_name => "David", :middle_initial => "H", :last_name => "Matthews", :street_address => "96 Village Drive", :city => "Smithfield West", :state => "NSW", :postcode => "2164", :email => "David.H.Matthews@trashymail.com", :birthday => "1957/7/18 00:00:00" | ||
| 801 | Person.create :gender => "female", :first_name => "Lilly", :middle_initial => "W", :last_name => "Bibi", :street_address => "37 Chatsworth Road", :city => "Camira", :state => "NSW", :postcode => "2469", :email => "Lilly.W.Bibi@pookmail.com", :birthday => "1965/11/10 00:00:00" | ||
| 802 | Person.create :gender => "male", :first_name => "Mason", :middle_initial => "Z", :last_name => "Rees", :street_address => "42 Shirley Street", :city => "Bahrs Scrub", :state => "QLD", :postcode => "4207", :email => "Mason.Z.Rees@trashymail.com", :birthday => "1971/8/11 00:00:00" | ||
| 803 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "E", :last_name => "Rees", :street_address => "59 High Street", :city => "Port Julia", :state => "SA", :postcode => "5575", :email => "Ethan.E.Rees@trashymail.com", :birthday => "1943/5/3 00:00:00" | ||
| 804 | Person.create :gender => "male", :first_name => "Joel", :middle_initial => "M", :last_name => "Woods", :street_address => "88 Taltarni Road", :city => "St Arnaud", :state => "VIC", :postcode => "3478", :email => "Joel.M.Woods@pookmail.com", :birthday => "1979/6/13 00:00:00" | ||
| 805 | Person.create :gender => "male", :first_name => "Bradley", :middle_initial => "L", :last_name => "Cook", :street_address => "49 Derry Street", :city => "Weengallon", :state => "QLD", :postcode => "4497", :email => "Bradley.L.Cook@trashymail.com", :birthday => "1959/7/19 00:00:00" | ||
| 806 | Person.create :gender => "female", :first_name => "Nicole", :middle_initial => "Z", :last_name => "Walters", :street_address => "33 Inglewood Court", :city => "Metcalfe East", :state => "VIC", :postcode => "3444", :email => "Nicole.Z.Walters@trashymail.com", :birthday => "1953/7/24 00:00:00" | ||
| 807 | Person.create :gender => "female", :first_name => "Rebecca", :middle_initial => "C", :last_name => "Anderson", :street_address => "90 Dossiter Street", :city => "Brooks Bay", :state => "TAS", :postcode => "7116", :email => "Rebecca.C.Anderson@trashymail.com", :birthday => "1968/11/24 00:00:00" | ||
| 808 | Person.create :gender => "female", :first_name => "Yasmin", :middle_initial => "N", :last_name => "Hooper", :street_address => "96 Shell Road", :city => "Ferguson", :state => "VIC", :postcode => "3237", :email => "Yasmin.N.Hooper@mailinator.com", :birthday => "1971/4/5 00:00:00" | ||
| 809 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "C", :last_name => "Burns", :street_address => "68 McGregor Street", :city => "Richardson", :state => "ACT", :postcode => "2905", :email => "Ava.C.Burns@dodgit.com", :birthday => "1968/6/30 00:00:00" | ||
| 810 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "R", :last_name => "Goodwin", :street_address => "80 Cedar Street", :city => "Valley Of Lagoons", :state => "QLD", :postcode => "4850", :email => "Tegan.R.Goodwin@mailinator.com", :birthday => "1976/7/11 00:00:00" | ||
| 811 | Person.create :gender => "female", :first_name => "Courtney", :middle_initial => "A", :last_name => "Wong", :street_address => "19 Ugoa Street", :city => "Booti Booti", :state => "NSW", :postcode => "2428", :email => "Courtney.A.Wong@pookmail.com", :birthday => "1973/3/23 00:00:00" | ||
| 812 | Person.create :gender => "male", :first_name => "Joshua", :middle_initial => "R", :last_name => "Cook", :street_address => "29 Arthur Street", :city => "Wuuluman", :state => "NSW", :postcode => "2820", :email => "Joshua.R.Cook@dodgit.com", :birthday => "1949/9/21 00:00:00" | ||
| 813 | Person.create :gender => "female", :first_name => "Niamh", :middle_initial => "B", :last_name => "Bailey", :street_address => "63 Swanston Street", :city => "Glenorchy", :state => "VIC", :postcode => "3385", :email => "Niamh.B.Bailey@mailinator.com", :birthday => "1958/2/6 00:00:00" | ||
| 814 | Person.create :gender => "female", :first_name => "Molly", :middle_initial => "A", :last_name => "Edwards", :street_address => "47 Barnett Street", :city => "Montumana", :state => "TAS", :postcode => "7321", :email => "Molly.A.Edwards@pookmail.com", :birthday => "1941/4/2 00:00:00" | ||
| 815 | Person.create :gender => "female", :first_name => "Alicia", :middle_initial => "H", :last_name => "Mitchell", :street_address => "40 Devon Street", :city => "Semaphore South", :state => "SA", :postcode => "5019", :email => "Alicia.H.Mitchell@mailinator.com", :birthday => "1950/9/27 00:00:00" | ||
| 816 | Person.create :gender => "male", :first_name => "Luke", :middle_initial => "M", :last_name => "Henry", :street_address => "68 Yangan Drive", :city => "Manilla", :state => "NSW", :postcode => "2346", :email => "Luke.M.Henry@trashymail.com", :birthday => "1946/2/19 00:00:00" | ||
| 817 | Person.create :gender => "female", :first_name => "Madison", :middle_initial => "R", :last_name => "Murray", :street_address => "44 Yangan Drive", :city => "Mayvale", :state => "NSW", :postcode => "2347", :email => "Madison.R.Murray@mailinator.com", :birthday => "1942/8/12 00:00:00" | ||
| 818 | Person.create :gender => "female", :first_name => "Hannah", :middle_initial => "J", :last_name => "Hayes", :street_address => "90 Larissa Court", :city => "Paringi", :state => "NSW", :postcode => "3500", :email => "Hannah.J.Hayes@spambob.com", :birthday => "1983/9/15 00:00:00" | ||
| 819 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "C", :last_name => "Brady", :street_address => "74 High Street", :city => "Tiddy Widdy Beach", :state => "SA", :postcode => "5571", :email => "Maddison.C.Brady@trashymail.com", :birthday => "1982/11/22 00:00:00" | ||
| 820 | Person.create :gender => "male", :first_name => "Ellis", :middle_initial => "I", :last_name => "Walsh", :street_address => "42 Banksia Street", :city => "Denham", :state => "WA", :postcode => "6537", :email => "Ellis.I.Walsh@trashymail.com", :birthday => "1963/4/18 00:00:00" | ||
| 821 | Person.create :gender => "male", :first_name => "Benjamin", :middle_initial => "M", :last_name => "Preston", :street_address => "44 Cofton Close", :city => "Dorrigo", :state => "NSW", :postcode => "2453", :email => "Benjamin.M.Preston@mailinator.com", :birthday => "1982/4/16 00:00:00" | ||
| 822 | Person.create :gender => "female", :first_name => "Amber", :middle_initial => "D", :last_name => "Henry", :street_address => "64 Forrest Road", :city => "Coolah", :state => "NSW", :postcode => "2843", :email => "Amber.D.Henry@dodgit.com", :birthday => "1945/6/1 00:00:00" | ||
| 823 | Person.create :gender => "female", :first_name => "Poppy", :middle_initial => "T", :last_name => "Burke", :street_address => "71 Springhill Bottom Road", :city => "Quamby Bend", :state => "TAS", :postcode => "7292", :email => "Poppy.T.Burke@mailinator.com", :birthday => "1967/2/1 00:00:00" | ||
| 824 | Person.create :gender => "female", :first_name => "Victoria", :middle_initial => "J", :last_name => "Austin", :street_address => "47 Ageston Road", :city => "Cannon Creek", :state => "QLD", :postcode => "4310", :email => "Victoria.J.Austin@trashymail.com", :birthday => "1984/8/25 00:00:00" | ||
| 825 | Person.create :gender => "female", :first_name => "Madison", :middle_initial => "W", :last_name => "Norris", :street_address => "47 Cubbine Road", :city => "Baandee", :state => "WA", :postcode => "6412", :email => "Madison.W.Norris@trashymail.com", :birthday => "1974/9/3 00:00:00" | ||
| 826 | Person.create :gender => "female", :first_name => "Kate", :middle_initial => "T", :last_name => "Houghton", :street_address => "94 Kaesler Road", :city => "Karoonda", :state => "SA", :postcode => "5307", :email => "Kate.T.Houghton@pookmail.com", :birthday => "1966/8/20 00:00:00" | ||
| 827 | Person.create :gender => "male", :first_name => "Tyler", :middle_initial => "K", :last_name => "Carter", :street_address => "65 Acheron Road", :city => "Sale", :state => "VIC", :postcode => "3850", :email => "Tyler.K.Carter@spambob.com", :birthday => "1985/9/25 00:00:00" | ||
| 828 | Person.create :gender => "male", :first_name => "Josh", :middle_initial => "E", :last_name => "Gill", :street_address => "42 Walpole Avenue", :city => "Curdievale", :state => "VIC", :postcode => "3268", :email => "Josh.E.Gill@trashymail.com", :birthday => "1975/11/18 00:00:00" | ||
| 829 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "L", :last_name => "Kaur", :street_address => "52 Dalgarno Street", :city => "Breeza", :state => "NSW", :postcode => "2381", :email => "Ava.L.Kaur@pookmail.com", :birthday => "1960/3/17 00:00:00" | ||
| 830 | Person.create :gender => "male", :first_name => "Charlie", :middle_initial => "E", :last_name => "Gibbons", :street_address => "88 Dora Creek", :city => "Tuntable Creek", :state => "NSW", :postcode => "2480", :email => "Charlie.E.Gibbons@dodgit.com", :birthday => "1955/10/3 00:00:00" | ||
| 831 | Person.create :gender => "male", :first_name => "Morgan", :middle_initial => "J", :last_name => "Pickering", :street_address => "68 Sullivan Court", :city => "Boinka", :state => "VIC", :postcode => "3490", :email => "Morgan.J.Pickering@mailinator.com", :birthday => "1942/6/24 00:00:00" | ||
| 832 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "D", :last_name => "Buckley", :street_address => "54 Kooljak Rd", :city => "Ambergate", :state => "WA", :postcode => "6280", :email => "Jake.D.Buckley@dodgit.com", :birthday => "1962/1/5 00:00:00" | ||
| 833 | Person.create :gender => "male", :first_name => "Matthew", :middle_initial => "L", :last_name => "Chamberlain", :street_address => "7 Noalimba Avenue", :city => "Yarrowyck", :state => "NSW", :postcode => "2358", :email => "Matthew.L.Chamberlain@spambob.com", :birthday => "1963/12/28 00:00:00" | ||
| 834 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "A", :last_name => "Austin", :street_address => "24 Mildura Street", :city => "Rocherlea", :state => "TAS", :postcode => "7248", :email => "Sam.A.Austin@mailinator.com", :birthday => "1955/5/27 00:00:00" | ||
| 835 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "S", :last_name => "Lowe", :street_address => "18 Loris Way", :city => "Morbinning", :state => "WA", :postcode => "6304", :email => "Sam.S.Lowe@spambob.com", :birthday => "1946/9/19 00:00:00" | ||
| 836 | Person.create :gender => "male", :first_name => "Bailey", :middle_initial => "K", :last_name => "Anderson", :street_address => "49 McLachlan Street", :city => "Toolondo", :state => "VIC", :postcode => "3401", :email => "Bailey.K.Anderson@pookmail.com", :birthday => "1956/6/23 00:00:00" | ||
| 837 | Person.create :gender => "female", :first_name => "Sofia", :middle_initial => "J", :last_name => "Gough", :street_address => "31 English Street", :city => "Murray Bridge East", :state => "SA", :postcode => "5253", :email => "Sofia.J.Gough@pookmail.com", :birthday => "1974/10/7 00:00:00" | ||
| 838 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "F", :last_name => "Tyler", :street_address => "12 Boobialla Street", :city => "Hay South", :state => "NSW", :postcode => "2711", :email => "Maddison.F.Tyler@trashymail.com", :birthday => "1971/1/27 00:00:00" | ||
| 839 | Person.create :gender => "female", :first_name => "Aimee", :middle_initial => "J", :last_name => "Pratt", :street_address => "91 Taylor Street", :city => "Picola", :state => "VIC", :postcode => "3639", :email => "Aimee.J.Pratt@dodgit.com", :birthday => "1980/2/14 00:00:00" | ||
| 840 | Person.create :gender => "female", :first_name => "Cerys", :middle_initial => "J", :last_name => "Hobbs", :street_address => "15 Ridge Road", :city => "Baffle Creek", :state => "QLD", :postcode => "4674", :email => "Cerys.J.Hobbs@dodgit.com", :birthday => "1944/9/1 00:00:00" | ||
| 841 | Person.create :gender => "male", :first_name => "Freddie", :middle_initial => "Y", :last_name => "Harding", :street_address => "64 Sinclair Street", :city => "Wallaroo Plain", :state => "SA", :postcode => "5556", :email => "Freddie.Y.Harding@pookmail.com", :birthday => "1956/2/2 00:00:00" | ||
| 842 | Person.create :gender => "female", :first_name => "Naomi", :middle_initial => "R", :last_name => "Fry", :street_address => "9 Roseda-Tinamba Road", :city => "Port Franklin", :state => "VIC", :postcode => "3964", :email => "Naomi.R.Fry@spambob.com", :birthday => "1984/11/15 00:00:00" | ||
| 843 | Person.create :gender => "male", :first_name => "Freddie", :middle_initial => "S", :last_name => "Mitchell", :street_address => "41 Walter Crescent", :city => "Benandarah", :state => "NSW", :postcode => "2536", :email => "Freddie.S.Mitchell@dodgit.com", :birthday => "1980/7/1 00:00:00" | ||
| 844 | Person.create :gender => "female", :first_name => "Elise", :middle_initial => "N", :last_name => "Browne", :street_address => "59 Kaesler Road", :city => "Koorine", :state => "SA", :postcode => "5279", :email => "Elise.N.Browne@pookmail.com", :birthday => "1982/3/20 00:00:00" | ||
| 845 | Person.create :gender => "female", :first_name => "Ella", :middle_initial => "C", :last_name => "Hammond", :street_address => "86 Cofton Close", :city => "North Dorrigo", :state => "NSW", :postcode => "2453", :email => "Ella.C.Hammond@spambob.com", :birthday => "1972/9/7 00:00:00" | ||
| 846 | Person.create :gender => "female", :first_name => "Leah", :middle_initial => "H", :last_name => "Miah", :street_address => "5 Rockhampton Qld", :city => "Plum Tree", :state => "QLD", :postcode => "4702", :email => "Leah.H.Miah@dodgit.com", :birthday => "1985/4/27 00:00:00" | ||
| 847 | Person.create :gender => "male", :first_name => "Daniel", :middle_initial => "R", :last_name => "Pratt", :street_address => "28 Sunraysia Road", :city => "Addington", :state => "VIC", :postcode => "3352", :email => "Daniel.R.Pratt@trashymail.com", :birthday => "1952/1/23 00:00:00" | ||
| 848 | Person.create :gender => "female", :first_name => "Ruby", :middle_initial => "J", :last_name => "Conway", :street_address => "50 Oriana Street", :city => "Lake Munmorah", :state => "NSW", :postcode => "2259", :email => "Ruby.J.Conway@trashymail.com", :birthday => "1963/11/17 00:00:00" | ||
| 849 | Person.create :gender => "male", :first_name => "Ellis", :middle_initial => "E", :last_name => "Day", :street_address => "90 Boobialla Street", :city => "Carrathool", :state => "NSW", :postcode => "2711", :email => "Ellis.E.Day@pookmail.com", :birthday => "1947/4/6 00:00:00" | ||
| 850 | Person.create :gender => "female", :first_name => "Millie", :middle_initial => "A", :last_name => "Hurst", :street_address => "1 Edgewater Close", :city => "Berrara", :state => "NSW", :postcode => "2540", :email => "Millie.A.Hurst@pookmail.com", :birthday => "1948/6/30 00:00:00" | ||
| 851 | Person.create :gender => "male", :first_name => "Ben", :middle_initial => "A", :last_name => "Dyer", :street_address => "68 Woodwark Crescent", :city => "Erub", :state => "QLD", :postcode => "4875", :email => "Ben.A.Dyer@dodgit.com", :birthday => "1966/7/28 00:00:00" | ||
| 852 | Person.create :gender => "female", :first_name => "Ellie", :middle_initial => "O", :last_name => "Savage", :street_address => "81 Shadforth Street", :city => "Kerang East", :state => "VIC", :postcode => "3579", :email => "Ellie.O.Savage@trashymail.com", :birthday => "1947/7/10 00:00:00" | ||
| 853 | Person.create :gender => "male", :first_name => "John", :middle_initial => "C", :last_name => "Blackburn", :street_address => "86 Hebbard Street", :city => "Dandenong North", :state => "VIC", :postcode => "3175", :email => "John.C.Blackburn@spambob.com", :birthday => "1984/4/22 00:00:00" | ||
| 854 | Person.create :gender => "female", :first_name => "Ellie", :middle_initial => "H", :last_name => "George", :street_address => "55 Atkinson Way", :city => "Roebourne", :state => "WA", :postcode => "6718", :email => "Ellie.H.George@dodgit.com", :birthday => "1952/5/19 00:00:00" | ||
| 855 | Person.create :gender => "male", :first_name => "Andrew", :middle_initial => "E", :last_name => "Whittaker", :street_address => "91 Springhill Bottom Road", :city => "Hawley Beach", :state => "TAS", :postcode => "7307", :email => "Andrew.E.Whittaker@mailinator.com", :birthday => "1960/8/7 00:00:00" | ||
| 856 | Person.create :gender => "male", :first_name => "Toby", :middle_initial => "C", :last_name => "O'ullivan", :street_address => "98 Hill Street", :city => "York Plains", :state => "TAS", :postcode => "7120", :email => "Toby.C.O'ullivan@pookmail.com", :birthday => "1942/5/5 00:00:00" | ||
| 857 | Person.create :gender => "male", :first_name => "Reece", :middle_initial => "M", :last_name => "Vaughan", :street_address => "73 Foreshore Road", :city => "Stratton", :state => "WA", :postcode => "6056", :email => "Reece.M.Vaughan@pookmail.com", :birthday => "1941/6/2 00:00:00" | ||
| 858 | Person.create :gender => "female", :first_name => "Maya", :middle_initial => "A", :last_name => "Morley", :street_address => "22 Bayview Road", :city => "Yaninee", :state => "SA", :postcode => "5653", :email => "Maya.A.Morley@spambob.com", :birthday => "1966/1/15 00:00:00" | ||
| 859 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "S", :last_name => "Hicks", :street_address => "53 Norton Street", :city => "Neutral Bay", :state => "NSW", :postcode => "2089", :email => "Ethan.S.Hicks@dodgit.com", :birthday => "1959/3/6 00:00:00" | ||
| 860 | Person.create :gender => "male", :first_name => "Cameron", :middle_initial => "N", :last_name => "Wood", :street_address => "71 Brown Street", :city => "Osborne Park", :state => "NSW", :postcode => "2066", :email => "Cameron.N.Wood@trashymail.com", :birthday => "1951/3/17 00:00:00" | ||
| 861 | Person.create :gender => "female", :first_name => "Bethany", :middle_initial => "A", :last_name => "Francis", :street_address => "57 Marloo Street", :city => "Hackney", :state => "SA", :postcode => "5069", :email => "Bethany.A.Francis@trashymail.com", :birthday => "1966/9/19 00:00:00" | ||
| 862 | Person.create :gender => "male", :first_name => "Alexander", :middle_initial => "C", :last_name => "Watkins", :street_address => "18 Daly Terrace", :city => "Mount Lawley", :state => "WA", :postcode => "6050", :email => "Alexander.C.Watkins@pookmail.com", :birthday => "1958/7/8 00:00:00" | ||
| 863 | Person.create :gender => "female", :first_name => "Aaliyah", :middle_initial => "R", :last_name => "Hanson", :street_address => "31 Frencham Street", :city => "Rand", :state => "NSW", :postcode => "2642", :email => "Aaliyah.R.Hanson@trashymail.com", :birthday => "1974/10/28 00:00:00" | ||
| 864 | Person.create :gender => "female", :first_name => "Erin", :middle_initial => "G", :last_name => "Lees", :street_address => "50 Carolina Park Road", :city => "Berkeley Vale", :state => "NSW", :postcode => "2261", :email => "Erin.G.Lees@trashymail.com", :birthday => "1968/10/26 00:00:00" | ||
| 865 | Person.create :gender => "female", :first_name => "Libby", :middle_initial => "F", :last_name => "Birch", :street_address => "63 Ageston Road", :city => "Anthony", :state => "QLD", :postcode => "4310", :email => "Libby.F.Birch@spambob.com", :birthday => "1973/1/22 00:00:00" | ||
| 866 | Person.create :gender => "female", :first_name => "Amelia", :middle_initial => "E", :last_name => "Hancock", :street_address => "63 Campbells River Road", :city => "Pine Grove", :state => "NSW", :postcode => "2829", :email => "Amelia.E.Hancock@spambob.com", :birthday => "1961/2/24 00:00:00" | ||
| 867 | Person.create :gender => "male", :first_name => "Harrison", :middle_initial => "L", :last_name => "Newman", :street_address => "6 Faulkner Street", :city => "Wards Mistake", :state => "NSW", :postcode => "2350", :email => "Harrison.L.Newman@spambob.com", :birthday => "1969/11/2 00:00:00" | ||
| 868 | Person.create :gender => "male", :first_name => "Declan", :middle_initial => "C", :last_name => "Whitehead", :street_address => "39 Blairgowrie Avenue", :city => "Ironmungy", :state => "NSW", :postcode => "2630", :email => "Declan.C.Whitehead@spambob.com", :birthday => "1971/1/2 00:00:00" | ||
| 869 | Person.create :gender => "male", :first_name => "Sebastian", :middle_initial => "T", :last_name => "Scott", :street_address => "98 Berambing Crescent", :city => "Stanhope Gardens", :state => "NSW", :postcode => "2768", :email => "Sebastian.T.Scott@mailinator.com", :birthday => "1962/3/14 00:00:00" | ||
| 870 | Person.create :gender => "male", :first_name => "Taylor", :middle_initial => "T", :last_name => "Morley", :street_address => "70 Round Drive", :city => "Eleebana", :state => "NSW", :postcode => "2282", :email => "Taylor.T.Morley@dodgit.com", :birthday => "1951/7/31 00:00:00" | ||
| 871 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "A", :last_name => "Lucas", :street_address => "58 Spencer Street", :city => "Cooloola Cove", :state => "QLD", :postcode => "4580", :email => "Sam.A.Lucas@spambob.com", :birthday => "1953/1/15 00:00:00" | ||
| 872 | Person.create :gender => "female", :first_name => "Grace", :middle_initial => "D", :last_name => "Hope", :street_address => "16 Wallum Court", :city => "Dunbible", :state => "NSW", :postcode => "2484", :email => "Grace.D.Hope@pookmail.com", :birthday => "1957/8/19 00:00:00" | ||
| 873 | Person.create :gender => "male", :first_name => "Aidan", :middle_initial => "M", :last_name => "Savage", :street_address => "64 Burnley Street", :city => "Willunga Hill", :state => "SA", :postcode => "5172", :email => "Aidan.M.Savage@trashymail.com", :birthday => "1946/3/3 00:00:00" | ||
| 874 | Person.create :gender => "female", :first_name => "Georgina", :middle_initial => "L", :last_name => "Macdonald", :street_address => "94 Norton Street", :city => "Bar Point", :state => "NSW", :postcode => "2083", :email => "Georgina.L.Macdonald@mailinator.com", :birthday => "1954/7/16 00:00:00" | ||
| 875 | Person.create :gender => "male", :first_name => "Luca", :middle_initial => "N", :last_name => "Lane", :street_address => "36 Berambing Crescent", :city => "Hawkesbury Heights", :state => "NSW", :postcode => "2777", :email => "Luca.N.Lane@trashymail.com", :birthday => "1970/8/3 00:00:00" | ||
| 876 | Person.create :gender => "female", :first_name => "Amy", :middle_initial => "D", :last_name => "Birch", :street_address => "9 Kerma Crescent", :city => "Clarence", :state => "NSW", :postcode => "2790", :email => "Amy.D.Birch@mailinator.com", :birthday => "1967/6/26 00:00:00" | ||
| 877 | Person.create :gender => "male", :first_name => "Riley", :middle_initial => "O", :last_name => "Cooper", :street_address => "22 Jacolite Street", :city => "Upper Swan", :state => "WA", :postcode => "6069", :email => "Riley.O.Cooper@spambob.com", :birthday => "1954/8/10 00:00:00" | ||
| 878 | Person.create :gender => "male", :first_name => "Samuel", :middle_initial => "A", :last_name => "Marsh", :street_address => "30 Shamrock Avenue", :city => "Mossy Point", :state => "NSW", :postcode => "2537", :email => "Samuel.A.Marsh@spambob.com", :birthday => "1985/1/7 00:00:00" | ||
| 879 | Person.create :gender => "female", :first_name => "Brooke", :middle_initial => "R", :last_name => "Wong", :street_address => "34 Davenport Street", :city => "Coolumbooka", :state => "NSW", :postcode => "2632", :email => "Brooke.R.Wong@spambob.com", :birthday => "1941/5/13 00:00:00" | ||
| 880 | Person.create :gender => "female", :first_name => "Mollie", :middle_initial => "J", :last_name => "Heath", :street_address => "56 Seninis Road", :city => "Idalia", :state => "QLD", :postcode => "4811", :email => "Mollie.J.Heath@spambob.com", :birthday => "1977/10/18 00:00:00" | ||
| 881 | Person.create :gender => "male", :first_name => "Harrison", :middle_initial => "T", :last_name => "Richards", :street_address => "13 Main Street", :city => "Devlins Pound", :state => "SA", :postcode => "5330", :email => "Harrison.T.Richards@pookmail.com", :birthday => "1965/10/31 00:00:00" | ||
| 882 | Person.create :gender => "male", :first_name => "Samuel", :middle_initial => "J", :last_name => "Glover", :street_address => "37 Gaggin Street", :city => "Tarro", :state => "NSW", :postcode => "2322", :email => "Samuel.J.Glover@pookmail.com", :birthday => "1971/1/18 00:00:00" | ||
| 883 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "M", :last_name => "Lord", :street_address => "89 Correa Place", :city => "Pinelands", :state => "NT", :postcode => "0829", :email => "Jacob.M.Lord@trashymail.com", :birthday => "1956/7/1 00:00:00" | ||
| 884 | Person.create :gender => "female", :first_name => "Charlotte", :middle_initial => "J", :last_name => "Thomson", :street_address => "19 Main Street", :city => "Schell Well", :state => "SA", :postcode => "5311", :email => "Charlotte.J.Thomson@spambob.com", :birthday => "1959/10/21 00:00:00" | ||
| 885 | Person.create :gender => "male", :first_name => "Kai", :middle_initial => "E", :last_name => "Rowley", :street_address => "86 Shell Road", :city => "Lavers Hill", :state => "VIC", :postcode => "3238", :email => "Kai.E.Rowley@pookmail.com", :birthday => "1961/11/6 00:00:00" | ||
| 886 | Person.create :gender => "male", :first_name => "Muhammad", :middle_initial => "P", :last_name => "Simpson", :street_address => "40 Porana Place", :city => "East Damboring", :state => "WA", :postcode => "6608", :email => "Muhammad.P.Simpson@dodgit.com", :birthday => "1982/4/6 00:00:00" | ||
| 887 | Person.create :gender => "male", :first_name => "Sebastian", :middle_initial => "A", :last_name => "Murray", :street_address => "82 Warren Avenue", :city => "Bonnells Bay", :state => "NSW", :postcode => "2264", :email => "Sebastian.A.Murray@mailinator.com", :birthday => "1954/11/4 00:00:00" | ||
| 888 | Person.create :gender => "female", :first_name => "Aaliyah", :middle_initial => "A", :last_name => "White", :street_address => "86 Wynyard Street", :city => "Jones Bridge", :state => "NSW", :postcode => "2720", :email => "Aaliyah.A.White@pookmail.com", :birthday => "1944/12/12 00:00:00" | ||
| 889 | Person.create :gender => "female", :first_name => "Faith", :middle_initial => "J", :last_name => "Ingram", :street_address => "48 Sale-Heyfield Road", :city => "Jeetho", :state => "VIC", :postcode => "3945", :email => "Faith.J.Ingram@dodgit.com", :birthday => "1953/5/27 00:00:00" | ||
| 890 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "B", :last_name => "Peters", :street_address => "34 Henry Street", :city => "Whittington", :state => "VIC", :postcode => "3219", :email => "Tegan.B.Peters@mailinator.com", :birthday => "1961/4/17 00:00:00" | ||
| 891 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "J", :last_name => "Doherty", :street_address => "28 Woerdens Road", :city => "Mangoola", :state => "NSW", :postcode => "2328", :email => "Maddison.J.Doherty@dodgit.com", :birthday => "1984/1/12 00:00:00" | ||
| 892 | Person.create :gender => "male", :first_name => "Lewis", :middle_initial => "N", :last_name => "Shepherd", :street_address => "97 Corio Street", :city => "Nalangil", :state => "VIC", :postcode => "3249", :email => "Lewis.N.Shepherd@dodgit.com", :birthday => "1950/1/4 00:00:00" | ||
| 893 | Person.create :gender => "female", :first_name => "Sophie", :middle_initial => "C", :last_name => "Baker", :street_address => "92 Dossiter Street", :city => "Levendale", :state => "TAS", :postcode => "7120", :email => "Sophie.C.Baker@dodgit.com", :birthday => "1957/10/8 00:00:00" | ||
| 894 | Person.create :gender => "male", :first_name => "Patrick", :middle_initial => "M", :last_name => "Ahmed", :street_address => "65 Link Road", :city => "Legerwood", :state => "TAS", :postcode => "7263", :email => "Patrick.M.Ahmed@trashymail.com", :birthday => "1978/8/20 00:00:00" | ||
| 895 | Person.create :gender => "male", :first_name => "Scott", :middle_initial => "L", :last_name => "Kennedy", :street_address => "97 Grandis Road", :city => "Rainbow Reach", :state => "NSW", :postcode => "2440", :email => "Scott.L.Kennedy@pookmail.com", :birthday => "1948/3/3 00:00:00" | ||
| 896 | Person.create :gender => "female", :first_name => "Aimee", :middle_initial => "J", :last_name => "Reeves", :street_address => "86 Atkinson Way", :city => "Pardoo", :state => "WA", :postcode => "6721", :email => "Aimee.J.Reeves@dodgit.com", :birthday => "1949/8/29 00:00:00" | ||
| 897 | Person.create :gender => "male", :first_name => "Evan", :middle_initial => "B", :last_name => "Woods", :street_address => "97 Cambridge Street", :city => "Glossodia", :state => "NSW", :postcode => "2756", :email => "Evan.B.Woods@mailinator.com", :birthday => "1966/4/2 00:00:00" | ||
| 898 | Person.create :gender => "female", :first_name => "Jennifer", :middle_initial => "J", :last_name => "Baldwin", :street_address => "35 Thule Drive", :city => "Truro", :state => "SA", :postcode => "5356", :email => "Jennifer.J.Baldwin@trashymail.com", :birthday => "1972/7/27 00:00:00" | ||
| 899 | Person.create :gender => "male", :first_name => "Louis", :middle_initial => "O", :last_name => "Holloway", :street_address => "25 Patton Street", :city => "Kooyong", :state => "VIC", :postcode => "3144", :email => "Louis.O.Holloway@mailinator.com", :birthday => "1948/4/11 00:00:00" | ||
| 900 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "S", :last_name => "Lane", :street_address => "88 Carba Road", :city => "Mount Gambier", :state => "SA", :postcode => "5291", :email => "Tom.S.Lane@dodgit.com", :birthday => "1969/12/8 00:00:00" | ||
| 901 | Person.create :gender => "female", :first_name => "Elise", :middle_initial => "R", :last_name => "Spencer", :street_address => "48 Carlisle Street", :city => "Longwood", :state => "VIC", :postcode => "3665", :email => "Elise.R.Spencer@trashymail.com", :birthday => "1965/3/9 00:00:00" | ||
| 902 | Person.create :gender => "female", :first_name => "Holly", :middle_initial => "D", :last_name => "Fisher", :street_address => "48 Mandible Street", :city => "Parkside", :state => "QLD", :postcode => "4825", :email => "Holly.D.Fisher@spambob.com", :birthday => "1982/2/6 00:00:00" | ||
| 903 | Person.create :gender => "female", :first_name => "Megan", :middle_initial => "D", :last_name => "Wilkins", :street_address => "89 Gaggin Street", :city => "Morpeth", :state => "NSW", :postcode => "2321", :email => "Megan.D.Wilkins@dodgit.com", :birthday => "1980/1/2 00:00:00" | ||
| 904 | Person.create :gender => "male", :first_name => "Leon", :middle_initial => "S", :last_name => "Dickinson", :street_address => "87 Foreshore Road", :city => "Herne Hill", :state => "WA", :postcode => "6056", :email => "Leon.S.Dickinson@trashymail.com", :birthday => "1962/4/19 00:00:00" | ||
| 905 | Person.create :gender => "female", :first_name => "Evie", :middle_initial => "H", :last_name => "Chamberlain", :street_address => "22 Maritime Avenue", :city => "Gnarabup", :state => "WA", :postcode => "6285", :email => "Evie.H.Chamberlain@spambob.com", :birthday => "1976/7/13 00:00:00" | ||
| 906 | Person.create :gender => "male", :first_name => "Oliver", :middle_initial => "H", :last_name => "Sharp", :street_address => "15 Acheron Road", :city => "Willung South", :state => "VIC", :postcode => "3844", :email => "Oliver.H.Sharp@spambob.com", :birthday => "1968/7/16 00:00:00" | ||
| 907 | Person.create :gender => "female", :first_name => "Isabella", :middle_initial => "J", :last_name => "Porter", :street_address => "65 Sale-Heyfield Road", :city => "Koorooman", :state => "VIC", :postcode => "3953", :email => "Isabella.J.Porter@dodgit.com", :birthday => "1972/8/7 00:00:00" | ||
| 908 | Person.create :gender => "male", :first_name => "Max", :middle_initial => "P", :last_name => "Myers", :street_address => "67 Ugoa Street", :city => "South West Rocks", :state => "NSW", :postcode => "2431", :email => "Max.P.Myers@spambob.com", :birthday => "1964/11/28 00:00:00" | ||
| 909 | Person.create :gender => "male", :first_name => "David", :middle_initial => "L", :last_name => "Ashton", :street_address => "72 Friar John Way", :city => "Safety Bay", :state => "WA", :postcode => "6169", :email => "David.L.Ashton@dodgit.com", :birthday => "1968/12/14 00:00:00" | ||
| 910 | Person.create :gender => "female", :first_name => "Morgan", :middle_initial => "S", :last_name => "Barton", :street_address => "75 Walters Street", :city => "Baddaginnie", :state => "VIC", :postcode => "3670", :email => "Morgan.S.Barton@mailinator.com", :birthday => "1946/1/11 00:00:00" | ||
| 911 | Person.create :gender => "female", :first_name => "Caitlin", :middle_initial => "T", :last_name => "Perkins", :street_address => "22 Wharf St", :city => "Glenworth Valley", :state => "NSW", :postcode => "2250", :email => "Caitlin.T.Perkins@spambob.com", :birthday => "1960/5/7 00:00:00" | ||
| 912 | Person.create :gender => "male", :first_name => "Matthew", :middle_initial => "K", :last_name => "Bell", :street_address => "13 Muscat Street", :city => "Beacon", :state => "WA", :postcode => "6472", :email => "Matthew.K.Bell@dodgit.com", :birthday => "1969/9/9 00:00:00" | ||
| 913 | Person.create :gender => "female", :first_name => "Katherine", :middle_initial => "F", :last_name => "Browne", :street_address => "73 Chatsworth Drive", :city => "Cloverdale", :state => "WA", :postcode => "6105", :email => "Katherine.F.Browne@mailinator.com", :birthday => "1948/12/22 00:00:00" | ||
| 914 | Person.create :gender => "female", :first_name => "Rachel", :middle_initial => "A", :last_name => "Freeman", :street_address => "1 Old Tenterfield Road", :city => "Simpkins Creek", :state => "NSW", :postcode => "2469", :email => "Rachel.A.Freeman@mailinator.com", :birthday => "1946/10/31 00:00:00" | ||
| 915 | Person.create :gender => "male", :first_name => "Jacob", :middle_initial => "I", :last_name => "Lewis", :street_address => "31 Elizabeth Street", :city => "Marys Creek", :state => "QLD", :postcode => "4570", :email => "Jacob.I.Lewis@spambob.com", :birthday => "1961/11/30 00:00:00" | ||
| 916 | Person.create :gender => "male", :first_name => "Leo", :middle_initial => "B", :last_name => "Tomlinson", :street_address => "27 Daly Terrace", :city => "Bassendean Dc", :state => "WA", :postcode => "6054", :email => "Leo.B.Tomlinson@trashymail.com", :birthday => "1975/10/31 00:00:00" | ||
| 917 | Person.create :gender => "female", :first_name => "Emily", :middle_initial => "J", :last_name => "Wallis", :street_address => "48 Eungella Road", :city => "Bogie", :state => "QLD", :postcode => "4805", :email => "Emily.J.Wallis@mailinator.com", :birthday => "1968/3/6 00:00:00" | ||
| 918 | Person.create :gender => "male", :first_name => "Hayden", :middle_initial => "P", :last_name => "Preston", :street_address => "52 Punchs Creek Road", :city => "Billa Billa", :state => "QLD", :postcode => "4390", :email => "Hayden.P.Preston@mailinator.com", :birthday => "1942/11/14 00:00:00" | ||
| 919 | Person.create :gender => "male", :first_name => "Harvey", :middle_initial => "J", :last_name => "Preston", :street_address => "10 Bette McNee Street", :city => "Wetuppa", :state => "NSW", :postcode => "2734", :email => "Harvey.J.Preston@trashymail.com", :birthday => "1944/8/25 00:00:00" | ||
| 920 | Person.create :gender => "male", :first_name => "Peter", :middle_initial => "Z", :last_name => "Gibson", :street_address => "14 Feather Street", :city => "Samford Valley", :state => "QLD", :postcode => "4520", :email => "Peter.Z.Gibson@mailinator.com", :birthday => "1968/1/29 00:00:00" | ||
| 921 | Person.create :gender => "female", :first_name => "Naomi", :middle_initial => "D", :last_name => "Morris", :street_address => "66 Border Drive", :city => "Gelston Park", :state => "NSW", :postcode => "2650", :email => "Naomi.D.Morris@pookmail.com", :birthday => "1976/3/8 00:00:00" | ||
| 922 | Person.create :gender => "female", :first_name => "Isobel", :middle_initial => "C", :last_name => "Hale", :street_address => "4 Cherokee Road", :city => "Shepherds Flat", :state => "VIC", :postcode => "3461", :email => "Isobel.C.Hale@spambob.com", :birthday => "1975/4/9 00:00:00" | ||
| 923 | Person.create :gender => "male", :first_name => "Robert", :middle_initial => "L", :last_name => "Long", :street_address => "86 Moruya Road", :city => "Marlowe", :state => "NSW", :postcode => "2622", :email => "Robert.L.Long@dodgit.com", :birthday => "1966/6/17 00:00:00" | ||
| 924 | Person.create :gender => "female", :first_name => "Laura", :middle_initial => "B", :last_name => "Campbell", :street_address => "59 Lowe Street", :city => "Warkon", :state => "QLD", :postcode => "4417", :email => "Laura.B.Campbell@pookmail.com", :birthday => "1945/8/26 00:00:00" | ||
| 925 | Person.create :gender => "female", :first_name => "Madeleine", :middle_initial => "Z", :last_name => "Young", :street_address => "86 Frencham Street", :city => "Geehi", :state => "NSW", :postcode => "2642", :email => "Madeleine.Z.Young@mailinator.com", :birthday => "1955/8/2 00:00:00" | ||
| 926 | Person.create :gender => "male", :first_name => "Lucas", :middle_initial => "B", :last_name => "Walton", :street_address => "16 Paradise Falls Road", :city => "Carboor", :state => "VIC", :postcode => "3678", :email => "Lucas.B.Walton@mailinator.com", :birthday => "1960/5/10 00:00:00" | ||
| 927 | Person.create :gender => "female", :first_name => "Rebecca", :middle_initial => "J", :last_name => "Dawson", :street_address => "31 Monteagle Road", :city => "Kippax", :state => "ACT", :postcode => "2615", :email => "Rebecca.J.Dawson@pookmail.com", :birthday => "1942/8/6 00:00:00" | ||
| 928 | Person.create :gender => "female", :first_name => "Eva", :middle_initial => "C", :last_name => "Ryan", :street_address => "63 Monteagle Road", :city => "Stirling", :state => "ACT", :postcode => "2611", :email => "Eva.C.Ryan@mailinator.com", :birthday => "1967/1/19 00:00:00" | ||
| 929 | Person.create :gender => "female", :first_name => "Harriet", :middle_initial => "A", :last_name => "Kaur", :street_address => "29 Yangan Drive", :city => "Colly Blue", :state => "NSW", :postcode => "2343", :email => "Harriet.A.Kaur@dodgit.com", :birthday => "1984/11/29 00:00:00" | ||
| 930 | Person.create :gender => "female", :first_name => "Sarah", :middle_initial => "Z", :last_name => "Conway", :street_address => "77 Shirley Street", :city => "Bahrs Scrub", :state => "QLD", :postcode => "4207", :email => "Sarah.Z.Conway@mailinator.com", :birthday => "1946/9/17 00:00:00" | ||
| 931 | Person.create :gender => "male", :first_name => "Freddie", :middle_initial => "E", :last_name => "Howells", :street_address => "21 McDowall Street", :city => "Highworth", :state => "QLD", :postcode => "4560", :email => "Freddie.E.Howells@spambob.com", :birthday => "1971/10/6 00:00:00" | ||
| 932 | Person.create :gender => "female", :first_name => "Ava", :middle_initial => "E", :last_name => "Perkins", :street_address => "30 Avondale Drive", :city => "Albion Park Rail", :state => "NSW", :postcode => "2527", :email => "Ava.E.Perkins@dodgit.com", :birthday => "1956/1/25 00:00:00" | ||
| 933 | Person.create :gender => "male", :first_name => "Matthew", :middle_initial => "K", :last_name => "Gallagher", :street_address => "44 Kogil Street", :city => "Warialda", :state => "NSW", :postcode => "2402", :email => "Matthew.K.Gallagher@dodgit.com", :birthday => "1964/6/28 00:00:00" | ||
| 934 | Person.create :gender => "male", :first_name => "Jude", :middle_initial => "A", :last_name => "Sharpe", :street_address => "6 Crofts Road", :city => "Wulgulmerang East", :state => "VIC", :postcode => "3885", :email => "Jude.A.Sharpe@trashymail.com", :birthday => "1955/1/10 00:00:00" | ||
| 935 | Person.create :gender => "female", :first_name => "Gracie", :middle_initial => "N", :last_name => "Flynn", :street_address => "31 Jacabina Court", :city => "Coalcliff", :state => "NSW", :postcode => "2508", :email => "Gracie.N.Flynn@pookmail.com", :birthday => "1966/12/23 00:00:00" | ||
| 936 | Person.create :gender => "male", :first_name => "Kai", :middle_initial => "I", :last_name => "Richardson", :street_address => "97 Ferny Avenue", :city => "Elliott Heads", :state => "QLD", :postcode => "4670", :email => "Kai.I.Richardson@pookmail.com", :birthday => "1963/1/28 00:00:00" | ||
| 937 | Person.create :gender => "male", :first_name => "Sebastian", :middle_initial => "L", :last_name => "Khan", :street_address => "80 Ulomogo Street", :city => "Mugga Hill", :state => "NSW", :postcode => "2830", :email => "Sebastian.L.Khan@dodgit.com", :birthday => "1940/1/21 00:00:00" | ||
| 938 | Person.create :gender => "male", :first_name => "Louie", :middle_initial => "G", :last_name => "Parkin", :street_address => "70 Tooraweenah Road", :city => "Jemalong", :state => "NSW", :postcode => "2871", :email => "Louie.G.Parkin@spambob.com", :birthday => "1946/5/15 00:00:00" | ||
| 939 | Person.create :gender => "male", :first_name => "Bailey", :middle_initial => "E", :last_name => "Barton", :street_address => "27 Cambridge Street", :city => "Glossodia", :state => "NSW", :postcode => "2756", :email => "Bailey.E.Barton@pookmail.com", :birthday => "1983/9/19 00:00:00" | ||
| 940 | Person.create :gender => "male", :first_name => "Charles", :middle_initial => "L", :last_name => "Curtis", :street_address => "15 Wharf St", :city => "East Gosford", :state => "NSW", :postcode => "2250", :email => "Charles.L.Curtis@spambob.com", :birthday => "1971/7/13 00:00:00" | ||
| 941 | Person.create :gender => "female", :first_name => "Lucy", :middle_initial => "G", :last_name => "Carey", :street_address => "89 Myrtle Street", :city => "Youarang", :state => "VIC", :postcode => "3728", :email => "Lucy.G.Carey@trashymail.com", :birthday => "1945/1/10 00:00:00" | ||
| 942 | Person.create :gender => "female", :first_name => "Samantha", :middle_initial => "K", :last_name => "Palmer", :street_address => "61 Henley Beach Road", :city => "Happy Valley", :state => "SA", :postcode => "5159", :email => "Samantha.K.Palmer@trashymail.com", :birthday => "1952/7/11 00:00:00" | ||
| 943 | Person.create :gender => "female", :first_name => "Maisie", :middle_initial => "H", :last_name => "Gibbs", :street_address => "20 Horsington Street", :city => "Mitcham", :state => "VIC", :postcode => "3132", :email => "Maisie.H.Gibbs@trashymail.com", :birthday => "1944/8/18 00:00:00" | ||
| 944 | Person.create :gender => "female", :first_name => "Chelsea", :middle_initial => "J", :last_name => "Patterson", :street_address => "86 Noalimba Avenue", :city => "Purlewaugh", :state => "NSW", :postcode => "2357", :email => "Chelsea.J.Patterson@mailinator.com", :birthday => "1955/1/5 00:00:00" | ||
| 945 | Person.create :gender => "female", :first_name => "Katie", :middle_initial => "L", :last_name => "Storey", :street_address => "6 Sunset Drive", :city => "Mexico", :state => "QLD", :postcode => "4728", :email => "Katie.L.Storey@pookmail.com", :birthday => "1943/4/21 00:00:00" | ||
| 946 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "F", :last_name => "Hunt", :street_address => "77 Ross Street", :city => "Numinbah Valley", :state => "QLD", :postcode => "4211", :email => "Sam.F.Hunt@pookmail.com", :birthday => "1970/3/19 00:00:00" | ||
| 947 | Person.create :gender => "female", :first_name => "Amelie", :middle_initial => "W", :last_name => "Brady", :street_address => "80 Jones Road", :city => "Doolandella", :state => "QLD", :postcode => "4077", :email => "Amelie.W.Brady@trashymail.com", :birthday => "1953/1/5 00:00:00" | ||
| 948 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "I", :last_name => "Hussain", :street_address => "49 Davis Street", :city => "Toowong", :state => "QLD", :postcode => "4066", :email => "Ethan.I.Hussain@spambob.com", :birthday => "1946/9/25 00:00:00" | ||
| 949 | Person.create :gender => "female", :first_name => "Evie", :middle_initial => "M", :last_name => "Dickinson", :street_address => "64 Yulara Drive", :city => "Wanarn", :state => "NT", :postcode => "0872", :email => "Evie.M.Dickinson@mailinator.com", :birthday => "1950/12/6 00:00:00" | ||
| 950 | Person.create :gender => "female", :first_name => "Naomi", :middle_initial => "R", :last_name => "Owen", :street_address => "46 Prince Street", :city => "Mcphersons Crossing", :state => "NSW", :postcode => "2460", :email => "Naomi.R.Owen@trashymail.com", :birthday => "1953/12/31 00:00:00" | ||
| 951 | Person.create :gender => "female", :first_name => "Emma", :middle_initial => "J", :last_name => "Barlow", :street_address => "82 Patton Street", :city => "Armadale", :state => "VIC", :postcode => "3143", :email => "Emma.J.Barlow@mailinator.com", :birthday => "1967/3/24 00:00:00" | ||
| 952 | Person.create :gender => "female", :first_name => "Sophia", :middle_initial => "J", :last_name => "Lloyd", :street_address => "61 Taylor Street", :city => "Kotupna", :state => "VIC", :postcode => "3638", :email => "Sophia.J.Lloyd@pookmail.com", :birthday => "1951/2/25 00:00:00" | ||
| 953 | Person.create :gender => "female", :first_name => "Summer", :middle_initial => "Z", :last_name => "Norris", :street_address => "15 Romawi Road", :city => "Clifton Creek", :state => "VIC", :postcode => "3875", :email => "Summer.Z.Norris@mailinator.com", :birthday => "1978/4/16 00:00:00" | ||
| 954 | Person.create :gender => "female", :first_name => "Poppy", :middle_initial => "A", :last_name => "Hancock", :street_address => "56 Spencer Street", :city => "Inskip", :state => "QLD", :postcode => "4581", :email => "Poppy.A.Hancock@spambob.com", :birthday => "1983/1/10 00:00:00" | ||
| 955 | Person.create :gender => "male", :first_name => "Leo", :middle_initial => "M", :last_name => "Russell", :street_address => "28 Boulter Close", :city => "Bamboo Creek", :state => "QLD", :postcode => "4860", :email => "Leo.M.Russell@pookmail.com", :birthday => "1951/11/10 00:00:00" | ||
| 956 | Person.create :gender => "female", :first_name => "Lucy", :middle_initial => "S", :last_name => "Connolly", :street_address => "40 Harris Street", :city => "Howqua", :state => "VIC", :postcode => "3723", :email => "Lucy.S.Connolly@pookmail.com", :birthday => "1967/4/18 00:00:00" | ||
| 957 | Person.create :gender => "female", :first_name => "Lola", :middle_initial => "J", :last_name => "Ryan", :street_address => "55 Flax Court", :city => "Kergunyah", :state => "VIC", :postcode => "3691", :email => "Lola.J.Ryan@trashymail.com", :birthday => "1949/5/19 00:00:00" | ||
| 958 | Person.create :gender => "female", :first_name => "Maisie", :middle_initial => "H", :last_name => "Daly", :street_address => "79 Woolnough Road", :city => "Burnside", :state => "SA", :postcode => "5066", :email => "Maisie.H.Daly@trashymail.com", :birthday => "1979/6/22 00:00:00" | ||
| 959 | Person.create :gender => "female", :first_name => "Libby", :middle_initial => "N", :last_name => "Kirk", :street_address => "20 Shell Road", :city => "Petticoat Creek", :state => "VIC", :postcode => "3233", :email => "Libby.N.Kirk@spambob.com", :birthday => "1948/4/1 00:00:00" | ||
| 960 | Person.create :gender => "female", :first_name => "Matilda", :middle_initial => "C", :last_name => "Ali", :street_address => "97 Normans Road", :city => "Tarrenlea", :state => "VIC", :postcode => "3315", :email => "Matilda.C.Ali@mailinator.com", :birthday => "1948/1/1 00:00:00" | ||
| 961 | Person.create :gender => "male", :first_name => "Finley", :middle_initial => "A", :last_name => "Wong", :street_address => "28 Marloo Street", :city => "Glynde", :state => "SA", :postcode => "5070", :email => "Finley.A.Wong@dodgit.com", :birthday => "1957/1/13 00:00:00" | ||
| 962 | Person.create :gender => "female", :first_name => "Isabelle", :middle_initial => "T", :last_name => "McCarthy", :street_address => "48 Marx Hill Road", :city => "Bielsdown Hills", :state => "NSW", :postcode => "2454", :email => "Isabelle.T.McCarthy@spambob.com", :birthday => "1946/5/5 00:00:00" | ||
| 963 | Person.create :gender => "male", :first_name => "Joshua", :middle_initial => "M", :last_name => "Miah", :street_address => "83 Cassinia Street", :city => "Four Corners", :state => "NSW", :postcode => "2716", :email => "Joshua.M.Miah@trashymail.com", :birthday => "1970/5/14 00:00:00" | ||
| 964 | Person.create :gender => "female", :first_name => "Holly", :middle_initial => "B", :last_name => "Anderson", :street_address => "68 Sale Street", :city => "Mullion Creek", :state => "NSW", :postcode => "2800", :email => "Holly.B.Anderson@spambob.com", :birthday => "1962/9/16 00:00:00" | ||
| 965 | Person.create :gender => "male", :first_name => "Zak", :middle_initial => "G", :last_name => "Moran", :street_address => "39 Taylor Street", :city => "Shepparton North", :state => "VIC", :postcode => "3631", :email => "Zak.G.Moran@mailinator.com", :birthday => "1975/7/12 00:00:00" | ||
| 966 | Person.create :gender => "male", :first_name => "Louis", :middle_initial => "E", :last_name => "Pickering", :street_address => "21 Farrar Parade", :city => "Coorow", :state => "WA", :postcode => "6515", :email => "Louis.E.Pickering@pookmail.com", :birthday => "1943/9/22 00:00:00" | ||
| 967 | Person.create :gender => "female", :first_name => "Eve", :middle_initial => "Z", :last_name => "Patterson", :street_address => "74 Walpole Avenue", :city => "Nirranda", :state => "VIC", :postcode => "3268", :email => "Eve.Z.Patterson@mailinator.com", :birthday => "1966/7/23 00:00:00" | ||
| 968 | Person.create :gender => "female", :first_name => "Rosie", :middle_initial => "H", :last_name => "Cooke", :street_address => "20 Romawi Road", :city => "Melwood", :state => "VIC", :postcode => "3875", :email => "Rosie.H.Cooke@mailinator.com", :birthday => "1943/6/9 00:00:00" | ||
| 969 | Person.create :gender => "female", :first_name => "Alexandra", :middle_initial => "R", :last_name => "Mahmood", :street_address => "53 Carlisle Street", :city => "Moglonemby", :state => "VIC", :postcode => "3666", :email => "Alexandra.R.Mahmood@trashymail.com", :birthday => "1979/6/23 00:00:00" | ||
| 970 | Person.create :gender => "male", :first_name => "Thomas", :middle_initial => "M", :last_name => "Joyce", :street_address => "44 Larissa Court", :city => "Mildura South", :state => "VIC", :postcode => "3501", :email => "Thomas.M.Joyce@spambob.com", :birthday => "1953/3/22 00:00:00" | ||
| 971 | Person.create :gender => "female", :first_name => "Lara", :middle_initial => "C", :last_name => "Ferguson", :street_address => "6 Jacabina Court", :city => "Tumbulgum", :state => "NSW", :postcode => "2490", :email => "Lara.C.Ferguson@pookmail.com", :birthday => "1977/11/24 00:00:00" | ||
| 972 | Person.create :gender => "female", :first_name => "Katherine", :middle_initial => "P", :last_name => "Sykes", :street_address => "40 Rose Street", :city => "Big Pats Creek", :state => "VIC", :postcode => "3799", :email => "Katherine.P.Sykes@mailinator.com", :birthday => "1972/9/27 00:00:00" | ||
| 973 | Person.create :gender => "male", :first_name => "Hayden", :middle_initial => "V", :last_name => "Todd", :street_address => "75 Carnegie Avenue", :city => "Burma Road", :state => "WA", :postcode => "6532", :email => "Hayden.V.Todd@dodgit.com", :birthday => "1973/6/13 00:00:00" | ||
| 974 | Person.create :gender => "female", :first_name => "Lilly", :middle_initial => "L", :last_name => "Macdonald", :street_address => "9 Romawi Road", :city => "Merrijig", :state => "VIC", :postcode => "3875", :email => "Lilly.L.Macdonald@pookmail.com", :birthday => "1961/4/23 00:00:00" | ||
| 975 | Person.create :gender => "female", :first_name => "Amelie", :middle_initial => "S", :last_name => "Stanley", :street_address => "98 McPherson Road", :city => "Thowgla Valley", :state => "VIC", :postcode => "3707", :email => "Amelie.S.Stanley@pookmail.com", :birthday => "1973/11/27 00:00:00" | ||
| 976 | Person.create :gender => "female", :first_name => "Eve", :middle_initial => "E", :last_name => "Sinclair", :street_address => "13 Little Myers Street", :city => "Long Forest", :state => "VIC", :postcode => "3340", :email => "Eve.E.Sinclair@spambob.com", :birthday => "1965/7/30 00:00:00" | ||
| 977 | Person.create :gender => "female", :first_name => "Jade", :middle_initial => "L", :last_name => "Davies", :street_address => "78 Kogil Street", :city => "Mungle", :state => "NSW", :postcode => "2408", :email => "Jade.L.Davies@pookmail.com", :birthday => "1972/12/29 00:00:00" | ||
| 978 | Person.create :gender => "male", :first_name => "Ethan", :middle_initial => "R", :last_name => "Barton", :street_address => "15 Border Drive", :city => "Borambola", :state => "NSW", :postcode => "2650", :email => "Ethan.R.Barton@pookmail.com", :birthday => "1965/4/22 00:00:00" | ||
| 979 | Person.create :gender => "male", :first_name => "Jake", :middle_initial => "V", :last_name => "Scott", :street_address => "11 Bailey Street", :city => "Toolong", :state => "VIC", :postcode => "3285", :email => "Jake.V.Scott@dodgit.com", :birthday => "1975/1/26 00:00:00" | ||
| 980 | Person.create :gender => "male", :first_name => "Tom", :middle_initial => "A", :last_name => "Owens", :street_address => "21 Ugoa Street", :city => "Mount George", :state => "NSW", :postcode => "2424", :email => "Tom.A.Owens@mailinator.com", :birthday => "1985/5/4 00:00:00" | ||
| 981 | Person.create :gender => "male", :first_name => "Freddie", :middle_initial => "A", :last_name => "Kemp", :street_address => "87 Kooljak Rd", :city => "Yelverton", :state => "WA", :postcode => "6280", :email => "Freddie.A.Kemp@dodgit.com", :birthday => "1970/7/30 00:00:00" | ||
| 982 | Person.create :gender => "male", :first_name => "Luke", :middle_initial => "E", :last_name => "Fuller", :street_address => "91 Ronald Crescent", :city => "South Trees", :state => "QLD", :postcode => "4680", :email => "Luke.E.Fuller@mailinator.com", :birthday => "1959/1/10 00:00:00" | ||
| 983 | Person.create :gender => "female", :first_name => "Tilly", :middle_initial => "T", :last_name => "Bray", :street_address => "32 Noalimba Avenue", :city => "Yarrowyck", :state => "NSW", :postcode => "2358", :email => "Tilly.T.Bray@pookmail.com", :birthday => "1941/10/20 00:00:00" | ||
| 984 | Person.create :gender => "male", :first_name => "Joel", :middle_initial => "H", :last_name => "Middleton", :street_address => "94 Hereford Avenue", :city => "Sandergrove", :state => "SA", :postcode => "5255", :email => "Joel.H.Middleton@spambob.com", :birthday => "1950/6/30 00:00:00" | ||
| 985 | Person.create :gender => "male", :first_name => "William", :middle_initial => "J", :last_name => "Boyle", :street_address => "63 Cherokee Road", :city => "Sailors Hill", :state => "VIC", :postcode => "3461", :email => "William.J.Boyle@dodgit.com", :birthday => "1948/12/9 00:00:00" | ||
| 986 | Person.create :gender => "male", :first_name => "Jonathan", :middle_initial => "S", :last_name => "Field", :street_address => "96 Yangan Drive", :city => "Parraweena", :state => "NSW", :postcode => "2339", :email => "Jonathan.S.Field@spambob.com", :birthday => "1984/4/26 00:00:00" | ||
| 987 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "S", :last_name => "Birch", :street_address => "42 Cornish Street", :city => "Travancore", :state => "VIC", :postcode => "3032", :email => "Sam.S.Birch@mailinator.com", :birthday => "1972/8/13 00:00:00" | ||
| 988 | Person.create :gender => "female", :first_name => "Jennifer", :middle_initial => "L", :last_name => "Nolan", :street_address => "3 Old Gayndah Road", :city => "Pallas Street Maryborough", :state => "QLD", :postcode => "4650", :email => "Jennifer.L.Nolan@spambob.com", :birthday => "1973/7/19 00:00:00" | ||
| 989 | Person.create :gender => "male", :first_name => "Benjamin", :middle_initial => "H", :last_name => "Gibson", :street_address => "38 Carlisle Street", :city => "Balmattum", :state => "VIC", :postcode => "3666", :email => "Benjamin.H.Gibson@trashymail.com", :birthday => "1960/10/1 00:00:00" | ||
| 990 | Person.create :gender => "male", :first_name => "Gabriel", :middle_initial => "C", :last_name => "Humphreys", :street_address => "11 Bresnahans Lane", :city => "Medway", :state => "NSW", :postcode => "2577", :email => "Gabriel.C.Humphreys@pookmail.com", :birthday => "1964/3/25 00:00:00" | ||
| 991 | Person.create :gender => "male", :first_name => "Morgan", :middle_initial => "F", :last_name => "Barton", :street_address => "24 Raglan Street", :city => "Warnung", :state => "QLD", :postcode => "4605", :email => "Morgan.F.Barton@mailinator.com", :birthday => "1985/9/26 00:00:00" | ||
| 992 | Person.create :gender => "female", :first_name => "Sophia", :middle_initial => "J", :last_name => "Talbot", :street_address => "59 Rimbanda Road", :city => "Yarrowford", :state => "NSW", :postcode => "2370", :email => "Sophia.J.Talbot@mailinator.com", :birthday => "1949/9/18 00:00:00" | ||
| 993 | Person.create :gender => "male", :first_name => "Gabriel", :middle_initial => "M", :last_name => "Finch", :street_address => "60 Banksia Street", :city => "Old Plains", :state => "WA", :postcode => "6569", :email => "Gabriel.M.Finch@mailinator.com", :birthday => "1966/2/13 00:00:00" | ||
| 994 | Person.create :gender => "male", :first_name => "Dylan", :middle_initial => "G", :last_name => "Riley", :street_address => "91 Campbells River Road", :city => "Combara", :state => "NSW", :postcode => "2829", :email => "Dylan.G.Riley@pookmail.com", :birthday => "1976/3/8 00:00:00" | ||
| 995 | Person.create :gender => "female", :first_name => "Maddison", :middle_initial => "J", :last_name => "Giles", :street_address => "79 Milbrodale Road", :city => "Obanvale", :state => "NSW", :postcode => "2330", :email => "Maddison.J.Giles@trashymail.com", :birthday => "1940/5/13 00:00:00" | ||
| 996 | Person.create :gender => "male", :first_name => "Nathan", :middle_initial => "A", :last_name => "Allen", :street_address => "80 McLachlan Street", :city => "Dooen", :state => "VIC", :postcode => "3401", :email => "Nathan.A.Allen@dodgit.com", :birthday => "1976/9/11 00:00:00" | ||
| 997 | Person.create :gender => "female", :first_name => "Chelsea", :middle_initial => "R", :last_name => "Leonard", :street_address => "2 Burnley Street", :city => "Hackham", :state => "SA", :postcode => "5163", :email => "Chelsea.R.Leonard@mailinator.com", :birthday => "1961/11/1 00:00:00" | ||
| 998 | Person.create :gender => "female", :first_name => "Francesca", :middle_initial => "J", :last_name => "Cross", :street_address => "72 Chapel Close", :city => "Brinsmead", :state => "QLD", :postcode => "4870", :email => "Francesca.J.Cross@pookmail.com", :birthday => "1943/9/30 00:00:00" | ||
| 999 | Person.create :gender => "male", :first_name => "Andrew", :middle_initial => "D", :last_name => "Atkins", :street_address => "59 Feather Street", :city => "Jollys Lookout", :state => "QLD", :postcode => "4520", :email => "Andrew.D.Atkins@pookmail.com", :birthday => "1954/4/3 00:00:00" | ||
| 1000 | Person.create :gender => "female", :first_name => "Tegan", :middle_initial => "D", :last_name => "Rowley", :street_address => "37 Isaac Road", :city => "Victoria Valley", :state => "TAS", :postcode => "7140", :email => "Tegan.D.Rowley@pookmail.com", :birthday => "1951/9/9 00:00:00" | ||
| 1001 | Person.create :gender => "female", :first_name => "Molly", :middle_initial => "L", :last_name => "Perry", :street_address => "12 Old Tenterfield Road", :city => "Lower Peacock", :state => "NSW", :postcode => "2469", :email => "Molly.L.Perry@trashymail.com", :birthday => "1970/2/5 00:00:00" | ||
| 1002 | Person.create :gender => "female", :first_name => "Kate", :middle_initial => "K", :last_name => "Stephenson", :street_address => "32 Henley Beach Road", :city => "Cleland", :state => "SA", :postcode => "5152", :email => "Kate.K.Stephenson@pookmail.com", :birthday => "1960/8/9 00:00:00" | ||
| 1003 | Person.create :gender => "female", :first_name => "Natasha", :middle_initial => "B", :last_name => "Short", :street_address => "14 Glen William Road", :city => "Gununa", :state => "QLD", :postcode => "4871", :email => "Natasha.B.Short@trashymail.com", :birthday => "1983/12/10 00:00:00" | ||
| 1004 | Person.create :gender => "female", :first_name => "Madison", :middle_initial => "H", :last_name => "Butler", :street_address => "19 Grandis Road", :city => "Greenhill", :state => "NSW", :postcode => "2440", :email => "Madison.H.Butler@dodgit.com", :birthday => "1960/12/9 00:00:00" | ||
| 1005 | Person.create :gender => "male", :first_name => "Sam", :middle_initial => "S", :last_name => "Bolton", :street_address => "44 Yarra Street", :city => "Newlyn North", :state => "VIC", :postcode => "3364", :email => "Sam.S.Bolton@mailinator.com", :birthday => "1974/11/16 00:00:00" | ||
| 1006 | Person.create :gender => "female", :first_name => "Daisy", :middle_initial => "L", :last_name => "Rahman", :street_address => "2 Crofts Road", :city => "Brodribb River", :state => "VIC", :postcode => "3888", :email => "Daisy.L.Rahman@mailinator.com", :birthday => "1946/8/14 00:00:00" | ||
| 1007 | Person.create :gender => "female", :first_name => "Eva", :middle_initial => "H", :last_name => "Lees", :street_address => "8 Bowden Street", :city => "Lilyfield", :state => "NSW", :postcode => "2040", :email => "Eva.H.Lees@dodgit.com", :birthday => "1968/8/9 00:00:00" | ||
| 1008 | Person.create :gender => "female", :first_name => "Holly", :middle_initial => "E", :last_name => "Hart", :street_address => "5 Parkes Road", :city => "Bonner", :state => "ACT", :postcode => "2914", :email => "Holly.E.Hart@pookmail.com", :birthday => "1947/5/5 00:00:00" | ||
| 1009 | Person.create :gender => "female", :first_name => "Charlotte", :middle_initial => "C", :last_name => "Bryan", :street_address => "71 Black Range Road", :city => "Doctor George Mountain", :state => "NSW", :postcode => "2550", :email => "Charlotte.C.Bryan@dodgit.com", :birthday => "1960/12/27 00:00:00" | ||
| 1010 | Person.create :gender => "male", :first_name => "Scott", :middle_initial => "I", :last_name => "Richardson", :street_address => "12 Old Tenterfield Road", :city => "Paddys Flat", :state => "NSW", :postcode => "2469", :email => "Scott.I.Richardson@mailinator.com", :birthday => "1985/8/20 00:00:00" | ||
| 1011 | Person.create :gender => "female", :first_name => "Sophia", :middle_initial => "T", :last_name => "Hicks", :street_address => "94 Whitehaven Crescent", :city => "Kamma", :state => "QLD", :postcode => "4865", :email => "Sophia.T.Hicks@dodgit.com", :birthday => "1953/7/22 00:00:00" | ||
| 1012 | Person.create :gender => "female", :first_name => "Brooke", :middle_initial => "C", :last_name => "Lyons", :street_address => "4 Stillwater Avenue", :city => "Wandana", :state => "WA", :postcode => "6532", :email => "Brooke.C.Lyons@spambob.com", :birthday => "1983/4/7 00:00:00" | ||
| 1013 | Person.create :gender => "female", :first_name => "Lydia", :middle_initial => "N", :last_name => "Simmons", :street_address => "19 Jones Street", :city => "Reynolds Neck", :state => "TAS", :postcode => "7304", :email => "Lydia.N.Simmons@pookmail.com", :birthday => "1972/4/25 00:00:00" | ||
| 1014 | Person.create :gender => "female", :first_name => "Isabella", :middle_initial => "B", :last_name => "Skinner", :street_address => "6 Hart Street", :city => "Parkville", :state => "NSW", :postcode => "2337", :email => "Isabella.B.Skinner@pookmail.com", :birthday => "1965/3/8 00:00:00" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_posts.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_posts.rb new file mode 100644 index 0000000..b528dc6 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_posts.rb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :posts, :force => true do |t| | ||
| 2 | t.column :subject, :string, :null => false | ||
| 3 | t.column :content, :text | ||
| 4 | t.column :category_id, :integer, :null => false | ||
| 5 | end | ||
| 6 | |||
| 7 | Post.create :subject => "Hello World", :content => "Um Text", :id => 1, :category_id => 1 | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_taggings.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_taggings.rb new file mode 100644 index 0000000..aeabaaf --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_taggings.rb | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :taggings, :force => true do |t| | ||
| 2 | t.column :tag_id, :integer, :null => false | ||
| 3 | t.column :taggable_id, :integer, :null => false | ||
| 4 | t.column :taggable_type, :string, :null => false | ||
| 5 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_tags.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_tags.rb new file mode 100644 index 0000000..71047e2 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_tags.rb | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :tags, :force => true do |t| | ||
| 2 | # t.column :post_id, :integer, :null => false | ||
| 3 | t.column :text, :text, :null => true | ||
| 4 | end | ||
| 5 | |||
| 6 | post = Post.find(1) | ||
| 7 | |||
| 8 | [ | ||
| 9 | 'Nunc in neque. Integer sed odio ac quam pellentesque suscipit. Cras posuere posuere est. Suspendisse est.', | ||
| 10 | 'In hac habitasse platea dictumst. Etiam eleifend est ac diam. Ut ac felis sit amet mi bibendum varius.', | ||
| 11 | 'Nullam sollicitudin tellus at ipsum. Duis mi eros, blandit sed, condimentum non, mattis vel, orci.', | ||
| 12 | 'Praesent auctor mollis leo. Nulla facilisi. Pellentesque habitant morbi tristique senectus et netus et', | ||
| 13 | 'malesuada fames ac turpis egestas. Donec non odio. Maecenas varius elit ut ante. Phasellus egestas, quam', | ||
| 14 | 'a congue euismod, diam urna gravida risus, at euismod lectus diam id sem. Vestibulum sed dolor et massa', | ||
| 15 | 'porta placerat. Etiam eget risus. Sed ornare. Vivamus in sapien. Maecenas non enim nec metus posuere', | ||
| 16 | 'vehicula. Donec rhoncus mauris at metus. Curabitur volutpat massa a metus. Aliquam ornare, neque ut', | ||
| 17 | 'tristique convallis, libero orci eleifend nibh, ac porta leo felis sed orci. Lorem ipsum dolor sit amet,', | ||
| 18 | 'Waffles' # This one is important, whereas the others are just padding | ||
| 19 | ].each do |text| | ||
| 20 | Tagging.create :taggable => post, :tag => Tag.create(:text => text) | ||
| 21 | end | ||
| 22 | |||
| 23 | Developer.find(:all).each do |developer| | ||
| 24 | [:country, :city, :state].each do |column| | ||
| 25 | Tagging.create( | ||
| 26 | :taggable => developer, | ||
| 27 | :tag => Tag.find_or_create_by_text(developer.send(column)) | ||
| 28 | ) | ||
| 29 | end | ||
| 30 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_thetas.rb b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_thetas.rb new file mode 100644 index 0000000..1712599 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/migrations/create_thetas.rb | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | ActiveRecord::Base.connection.create_table :thetas, :force => true do |t| | ||
| 2 | t.column :name, :string, :null => false | ||
| 3 | t.column :created_at, :datetime, :null => false | ||
| 4 | t.column :updated_at, :datetime, :null => false | ||
| 5 | end | ||
| 6 | |||
| 7 | Theta.create :name => "one" | ||
| 8 | Theta.create :name => "two" | ||
| 9 | Theta.create :name => "three" | ||
| 10 | Theta.create :name => "four" | ||
| 11 | Theta.create :name => "five" | ||
| 12 | Theta.create :name => "six" | ||
| 13 | Theta.create :name => "seven" | ||
| 14 | Theta.create :name => "eight" | ||
| 15 | Theta.create :name => "nine" | ||
| 16 | Theta.create :name => "ten" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/mysql.rb b/vendor/plugins/thinking-sphinx/features/support/db/mysql.rb new file mode 100644 index 0000000..84232a7 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/mysql.rb | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | require 'active_record' | ||
| 2 | Database = defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql' | ||
| 3 | require "active_record/connection_adapters/#{Database}_adapter" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/db/postgresql.rb b/vendor/plugins/thinking-sphinx/features/support/db/postgresql.rb new file mode 100644 index 0000000..20392e1 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/db/postgresql.rb | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | require 'active_record' | ||
| 2 | Database = defined?(JRUBY_VERSION) ? 'jdbcpostgresql' : 'postgresql' | ||
| 3 | require "active_record/connection_adapters/#{Database}_adapter" | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/env.rb b/vendor/plugins/thinking-sphinx/features/support/env.rb new file mode 100644 index 0000000..c837d8c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/env.rb | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | require 'rubygems' | ||
| 2 | require 'cucumber' | ||
| 3 | require 'spec' | ||
| 4 | require 'fileutils' | ||
| 5 | require 'ginger' | ||
| 6 | require 'will_paginate' \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/lib/generic_delta_handler.rb b/vendor/plugins/thinking-sphinx/features/support/lib/generic_delta_handler.rb new file mode 100644 index 0000000..7e9f96b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/lib/generic_delta_handler.rb | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | class GenericDeltaHandler < ThinkingSphinx::Deltas::DefaultDelta | ||
| 2 | |||
| 3 | def index(model, instance = nil) | ||
| 4 | #do nothing but set a bit for every record | ||
| 5 | #this is just a demonstration of extensibility | ||
| 6 | model.update_all(:changed_by_generic => true) | ||
| 7 | end | ||
| 8 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/alpha.rb b/vendor/plugins/thinking-sphinx/features/support/models/alpha.rb new file mode 100644 index 0000000..0973c1c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/alpha.rb | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | class Alpha < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes :name, :sortable => true | ||
| 4 | |||
| 5 | has value, cost, created_at, created_on | ||
| 6 | |||
| 7 | set_property :field_weights => {"name" => 10} | ||
| 8 | end | ||
| 9 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/animal.rb b/vendor/plugins/thinking-sphinx/features/support/models/animal.rb new file mode 100644 index 0000000..75f8cc5 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/animal.rb | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | class Animal < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes name, :sortable => true | ||
| 4 | end | ||
| 5 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/beta.rb b/vendor/plugins/thinking-sphinx/features/support/models/beta.rb new file mode 100644 index 0000000..096a78c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/beta.rb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | class Beta < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes :name, :sortable => true | ||
| 4 | |||
| 5 | set_property :delta => true | ||
| 6 | end | ||
| 7 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/box.rb b/vendor/plugins/thinking-sphinx/features/support/models/box.rb new file mode 100644 index 0000000..bd948c4 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/box.rb | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | class Box < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes width, :as => :width_field | ||
| 4 | |||
| 5 | has width, length, depth | ||
| 6 | has [width, length, depth], :as => :dimensions | ||
| 7 | end | ||
| 8 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/cat.rb b/vendor/plugins/thinking-sphinx/features/support/models/cat.rb new file mode 100644 index 0000000..f6cf75a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/cat.rb | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | class Cat < Animal | ||
| 2 | # | ||
| 3 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/category.rb b/vendor/plugins/thinking-sphinx/features/support/models/category.rb new file mode 100644 index 0000000..ea52b65 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/category.rb | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | class Category < ActiveRecord::Base | ||
| 2 | has_many :posts | ||
| 3 | has_many :comments | ||
| 4 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/comment.rb b/vendor/plugins/thinking-sphinx/features/support/models/comment.rb new file mode 100644 index 0000000..a93451c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/comment.rb | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | class Comment < ActiveRecord::Base | ||
| 2 | belongs_to :post | ||
| 3 | belongs_to :category | ||
| 4 | |||
| 5 | define_index do | ||
| 6 | indexes :content | ||
| 7 | |||
| 8 | has category.name, :facet => true, :as => :category_name, :type => :string | ||
| 9 | end | ||
| 10 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/delayed_beta.rb b/vendor/plugins/thinking-sphinx/features/support/models/delayed_beta.rb new file mode 100644 index 0000000..ccd9846 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/delayed_beta.rb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | class DelayedBeta < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes :name, :sortable => true | ||
| 4 | |||
| 5 | set_property :delta => :delayed | ||
| 6 | end | ||
| 7 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/developer.rb b/vendor/plugins/thinking-sphinx/features/support/models/developer.rb new file mode 100644 index 0000000..d461ebc --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/developer.rb | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | class Developer < ActiveRecord::Base | ||
| 2 | has_many :taggings, :as => :taggable | ||
| 3 | has_many :tags, :through => :taggings | ||
| 4 | |||
| 5 | define_index do | ||
| 6 | indexes country, :facet => true | ||
| 7 | indexes state, :facet => true | ||
| 8 | has age, :facet => true | ||
| 9 | has tags(:id), :as => :tag_ids, :facet => true | ||
| 10 | facet city | ||
| 11 | end | ||
| 12 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/extensible_beta.rb b/vendor/plugins/thinking-sphinx/features/support/models/extensible_beta.rb new file mode 100644 index 0000000..40b64f5 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/extensible_beta.rb | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | require File.join(File.dirname(__FILE__), "..", "lib", "generic_delta_handler") | ||
| 2 | |||
| 3 | class ExtensibleBeta < ActiveRecord::Base | ||
| 4 | define_index do | ||
| 5 | indexes :name, :sortable => true | ||
| 6 | |||
| 7 | set_property :delta => GenericDeltaHandler | ||
| 8 | end | ||
| 9 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/gamma.rb b/vendor/plugins/thinking-sphinx/features/support/models/gamma.rb new file mode 100644 index 0000000..5e9d259 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/gamma.rb | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | class Gamma < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes :name, :sortable => true | ||
| 4 | end | ||
| 5 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/person.rb b/vendor/plugins/thinking-sphinx/features/support/models/person.rb new file mode 100644 index 0000000..62a0a96 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/person.rb | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | class Person < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes first_name, last_name, :sortable => true | ||
| 4 | |||
| 5 | has [first_name, middle_initial, last_name], :as => :name_sort | ||
| 6 | has birthday | ||
| 7 | has gender, :facet => true | ||
| 8 | end | ||
| 9 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/post.rb b/vendor/plugins/thinking-sphinx/features/support/models/post.rb new file mode 100644 index 0000000..430d17c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/post.rb | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | class Post < ActiveRecord::Base | ||
| 2 | has_many :comments, :dependent => :destroy | ||
| 3 | has_many :taggings, :as => :taggable | ||
| 4 | has_many :tags, :through => :taggings | ||
| 5 | belongs_to :category | ||
| 6 | |||
| 7 | define_index do | ||
| 8 | indexes subject | ||
| 9 | indexes content | ||
| 10 | indexes tags.text, :as => :tags | ||
| 11 | indexes comments.content, :as => :comments | ||
| 12 | |||
| 13 | has comments(:id), :as => :comment_ids, :source => :ranged_query | ||
| 14 | has category.name, :facet => true, :as => :category_name, :type => :string | ||
| 15 | end | ||
| 16 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/tag.rb b/vendor/plugins/thinking-sphinx/features/support/models/tag.rb new file mode 100644 index 0000000..30992e8 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/tag.rb | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | class Tag < ActiveRecord::Base | ||
| 2 | belongs_to :post | ||
| 3 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/tagging.rb b/vendor/plugins/thinking-sphinx/features/support/models/tagging.rb new file mode 100644 index 0000000..33daf86 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/tagging.rb | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | class Tagging < ActiveRecord::Base | ||
| 2 | belongs_to :tag | ||
| 3 | belongs_to :taggable, :polymorphic => true | ||
| 4 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/models/theta.rb b/vendor/plugins/thinking-sphinx/features/support/models/theta.rb new file mode 100644 index 0000000..0ce91d6 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/models/theta.rb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | class Theta < ActiveRecord::Base | ||
| 2 | define_index do | ||
| 3 | indexes :name, :sortable => true | ||
| 4 | |||
| 5 | set_property :delta => :datetime, :threshold => 1.hour | ||
| 6 | end | ||
| 7 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/post_database.rb b/vendor/plugins/thinking-sphinx/features/support/post_database.rb new file mode 100644 index 0000000..51cefb5 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/post_database.rb | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | $:.unshift File.dirname(__FILE__) + '/../../lib' | ||
| 2 | |||
| 3 | require 'lib/thinking_sphinx' | ||
| 4 | |||
| 5 | %w( tmp/config tmp/log tmp/db/sphinx/development ).each do |path| | ||
| 6 | FileUtils.mkdir_p "#{Dir.pwd}/#{path}" | ||
| 7 | end | ||
| 8 | |||
| 9 | Kernel.const_set :RAILS_ROOT, "#{Dir.pwd}/tmp" unless defined?(RAILS_ROOT) | ||
| 10 | |||
| 11 | at_exit do | ||
| 12 | ThinkingSphinx::Configuration.instance.controller.stop | ||
| 13 | sleep(1) # Ensure Sphinx has shut down completely | ||
| 14 | FileUtils.rm_r "#{Dir.pwd}/tmp" | ||
| 15 | end | ||
| 16 | |||
| 17 | # Add log file | ||
| 18 | ActiveRecord::Base.logger = Logger.new open("tmp/active_record.log", "a") | ||
| 19 | |||
| 20 | ThinkingSphinx.deltas_enabled = false | ||
| 21 | |||
| 22 | # Load Models | ||
| 23 | Dir["features/support/models/*.rb"].sort.each do |file| | ||
| 24 | require file.gsub(/\.rb$/, '') | ||
| 25 | end | ||
| 26 | |||
| 27 | # Set up database tables and records | ||
| 28 | Dir["features/support/db/migrations/*.rb"].each do |file| | ||
| 29 | require file.gsub(/\.rb$/, '') | ||
| 30 | end | ||
| 31 | |||
| 32 | ThinkingSphinx.deltas_enabled = true | ||
| 33 | ThinkingSphinx.suppress_delta_output = true | ||
| 34 | |||
| 35 | ThinkingSphinx::Configuration.instance.build | ||
| 36 | ThinkingSphinx::Configuration.instance.controller.index | ||
| 37 | ThinkingSphinx::Configuration.instance.controller.start | ||
diff --git a/vendor/plugins/thinking-sphinx/features/support/z.rb b/vendor/plugins/thinking-sphinx/features/support/z.rb new file mode 100644 index 0000000..e7ad8b3 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/features/support/z.rb | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | # This file exists because Cucumber likes to auto-load all ruby files | ||
| 2 | puts <<-MESSAGE | ||
| 3 | Cucumber 0.1.13 defaults to loading all ruby files within the features folder, | ||
| 4 | with something approaching reverse-alphabetical order, and preferring the | ||
| 5 | features/support folder over everything else. This is annoying, because some | ||
| 6 | files need to be loaded before others (and others perhaps not at all, given | ||
| 7 | missing dependencies). Hence this place-holder imaginatively named 'z.rb', to | ||
| 8 | force this message. | ||
| 9 | |||
| 10 | A work-around is to use cucumber profiles. You will find the default profile in | ||
| 11 | cucumber.yml should serve your needs fine, unless you add new step definitions. | ||
| 12 | When you do that, you can regenerate the YAML file by running: | ||
| 13 | rake cucumber_defaults | ||
| 14 | |||
| 15 | And then run specific features as follows is slightly more verbose, but it | ||
| 16 | works, whereas this doesn't. | ||
| 17 | cucumber -p default features/something.feature | ||
| 18 | MESSAGE | ||
| 19 | exit 0 \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/ginger_scenarios.rb b/vendor/plugins/thinking-sphinx/ginger_scenarios.rb new file mode 100644 index 0000000..bd9f0d6 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/ginger_scenarios.rb | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | require 'ginger' | ||
| 2 | |||
| 3 | Ginger.configure do |config| | ||
| 4 | config.aliases["active_record"] = "activerecord" | ||
| 5 | config.aliases["active_support"] = "activesupport" | ||
| 6 | |||
| 7 | ar_1_2_6 = Ginger::Scenario.new | ||
| 8 | ar_1_2_6[/^active_?support$/] = "1.4.4" | ||
| 9 | ar_1_2_6[/^active_?record$/] = "1.15.6" | ||
| 10 | |||
| 11 | ar_2_0_4 = Ginger::Scenario.new | ||
| 12 | ar_2_0_4[/^active_?support$/] = "2.0.4" | ||
| 13 | ar_2_0_4[/^active_?record$/] = "2.0.4" | ||
| 14 | |||
| 15 | ar_2_1_2 = Ginger::Scenario.new | ||
| 16 | ar_2_1_2[/^active_?support$/] = "2.1.2" | ||
| 17 | ar_2_1_2[/^active_?record$/] = "2.1.2" | ||
| 18 | |||
| 19 | ar_2_2_0 = Ginger::Scenario.new | ||
| 20 | ar_2_2_0[/^active_?support$/] = "2.2.0" | ||
| 21 | ar_2_2_0[/^active_?record$/] = "2.2.0" | ||
| 22 | |||
| 23 | ar_2_3_0 = Ginger::Scenario.new | ||
| 24 | ar_2_3_0[/^active_?support$/] = "2.3.0" | ||
| 25 | ar_2_3_0[/^active_?record$/] = "2.3.0" | ||
| 26 | |||
| 27 | config.scenarios << ar_1_2_6 << ar_2_0_4 << ar_2_1_2 << ar_2_2_0 << ar_2_3_0 | ||
| 28 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/init.rb b/vendor/plugins/thinking-sphinx/init.rb new file mode 100644 index 0000000..a7e3920 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/init.rb | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | require 'thinking_sphinx' | ||
| 2 | |||
| 3 | if Rails::VERSION::STRING.to_f < 2.1 | ||
| 4 | ThinkingSphinx::Configuration.instance.load_models | ||
| 5 | end | ||
| 6 | |||
| 7 | if Rails::VERSION::STRING.to_f > 1.2 | ||
| 8 | require 'action_controller/dispatcher' | ||
| 9 | ActionController::Dispatcher.to_prepare :thinking_sphinx do | ||
| 10 | ThinkingSphinx::Configuration.instance.load_models | ||
| 11 | end | ||
| 12 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx.rb new file mode 100644 index 0000000..745643f --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx.rb | |||
| @@ -0,0 +1,180 @@ | |||
| 1 | Dir[File.join(File.dirname(__FILE__), '../vendor/*/lib')].each do |path| | ||
| 2 | $LOAD_PATH.unshift path | ||
| 3 | end | ||
| 4 | |||
| 5 | require 'active_record' | ||
| 6 | require 'riddle' | ||
| 7 | require 'after_commit' | ||
| 8 | |||
| 9 | require 'thinking_sphinx/core/string' | ||
| 10 | require 'thinking_sphinx/active_record' | ||
| 11 | require 'thinking_sphinx/association' | ||
| 12 | require 'thinking_sphinx/attribute' | ||
| 13 | require 'thinking_sphinx/collection' | ||
| 14 | require 'thinking_sphinx/configuration' | ||
| 15 | require 'thinking_sphinx/facet' | ||
| 16 | require 'thinking_sphinx/class_facet' | ||
| 17 | require 'thinking_sphinx/facet_collection' | ||
| 18 | require 'thinking_sphinx/field' | ||
| 19 | require 'thinking_sphinx/index' | ||
| 20 | require 'thinking_sphinx/rails_additions' | ||
| 21 | require 'thinking_sphinx/search' | ||
| 22 | require 'thinking_sphinx/deltas' | ||
| 23 | |||
| 24 | require 'thinking_sphinx/adapters/abstract_adapter' | ||
| 25 | require 'thinking_sphinx/adapters/mysql_adapter' | ||
| 26 | require 'thinking_sphinx/adapters/postgresql_adapter' | ||
| 27 | |||
| 28 | ActiveRecord::Base.send(:include, ThinkingSphinx::ActiveRecord) | ||
| 29 | |||
| 30 | Merb::Plugins.add_rakefiles( | ||
| 31 | File.join(File.dirname(__FILE__), "thinking_sphinx", "tasks") | ||
| 32 | ) if defined?(Merb) | ||
| 33 | |||
| 34 | module ThinkingSphinx | ||
| 35 | module Version #:nodoc: | ||
| 36 | Major = 1 | ||
| 37 | Minor = 1 | ||
| 38 | Tiny = 6 | ||
| 39 | |||
| 40 | String = [Major, Minor, Tiny].join('.') | ||
| 41 | end | ||
| 42 | |||
| 43 | # A ConnectionError will get thrown when a connection to Sphinx can't be | ||
| 44 | # made. | ||
| 45 | class ConnectionError < StandardError | ||
| 46 | end | ||
| 47 | |||
| 48 | # A StaleIdsException is thrown by Collection.instances_from_matches if there | ||
| 49 | # are records in Sphinx but not in the database, so the search can be retried. | ||
| 50 | class StaleIdsException < StandardError | ||
| 51 | attr_accessor :ids | ||
| 52 | def initialize(ids) | ||
| 53 | self.ids = ids | ||
| 54 | end | ||
| 55 | end | ||
| 56 | |||
| 57 | # The collection of indexed models. Keep in mind that Rails lazily loads | ||
| 58 | # its classes, so this may not actually be populated with _all_ the models | ||
| 59 | # that have Sphinx indexes. | ||
| 60 | def self.indexed_models | ||
| 61 | @@indexed_models ||= [] | ||
| 62 | end | ||
| 63 | |||
| 64 | def self.unique_id_expression(offset = nil) | ||
| 65 | "* #{ThinkingSphinx.indexed_models.size} + #{offset || 0}" | ||
| 66 | end | ||
| 67 | |||
| 68 | # Check if index definition is disabled. | ||
| 69 | # | ||
| 70 | def self.define_indexes? | ||
| 71 | @@define_indexes = true unless defined?(@@define_indexes) | ||
| 72 | @@define_indexes == true | ||
| 73 | end | ||
| 74 | |||
| 75 | # Enable/disable indexes - you may want to do this while migrating data. | ||
| 76 | # | ||
| 77 | # ThinkingSphinx.define_indexes = false | ||
| 78 | # | ||
| 79 | def self.define_indexes=(value) | ||
| 80 | @@define_indexes = value | ||
| 81 | end | ||
| 82 | |||
| 83 | @@deltas_enabled = nil | ||
| 84 | |||
| 85 | # Check if delta indexing is enabled. | ||
| 86 | # | ||
| 87 | def self.deltas_enabled? | ||
| 88 | @@deltas_enabled = (ThinkingSphinx::Configuration.environment != 'test') if @@deltas_enabled.nil? | ||
| 89 | @@deltas_enabled | ||
| 90 | end | ||
| 91 | |||
| 92 | # Enable/disable all delta indexing. | ||
| 93 | # | ||
| 94 | # ThinkingSphinx.deltas_enabled = false | ||
| 95 | # | ||
| 96 | def self.deltas_enabled=(value) | ||
| 97 | @@deltas_enabled = value | ||
| 98 | end | ||
| 99 | |||
| 100 | @@updates_enabled = nil | ||
| 101 | |||
| 102 | # Check if updates are enabled. True by default, unless within the test | ||
| 103 | # environment. | ||
| 104 | # | ||
| 105 | def self.updates_enabled? | ||
| 106 | @@updates_enabled = (ThinkingSphinx::Configuration.environment != 'test') if @@updates_enabled.nil? | ||
| 107 | @@updates_enabled | ||
| 108 | end | ||
| 109 | |||
| 110 | # Enable/disable updates to Sphinx | ||
| 111 | # | ||
| 112 | # ThinkingSphinx.updates_enabled = false | ||
| 113 | # | ||
| 114 | def self.updates_enabled=(value) | ||
| 115 | @@updates_enabled = value | ||
| 116 | end | ||
| 117 | |||
| 118 | @@suppress_delta_output = false | ||
| 119 | |||
| 120 | def self.suppress_delta_output? | ||
| 121 | @@suppress_delta_output | ||
| 122 | end | ||
| 123 | |||
| 124 | def self.suppress_delta_output=(value) | ||
| 125 | @@suppress_delta_output = value | ||
| 126 | end | ||
| 127 | |||
| 128 | # Checks to see if MySQL will allow simplistic GROUP BY statements. If not, | ||
| 129 | # or if not using MySQL, this will return false. | ||
| 130 | # | ||
| 131 | def self.use_group_by_shortcut? | ||
| 132 | !!( | ||
| 133 | mysql? && ::ActiveRecord::Base.connection.select_all( | ||
| 134 | "SELECT @@global.sql_mode, @@session.sql_mode;" | ||
| 135 | ).all? { |key,value| value.nil? || value[/ONLY_FULL_GROUP_BY/].nil? } | ||
| 136 | ) | ||
| 137 | end | ||
| 138 | |||
| 139 | def self.sphinx_running? | ||
| 140 | !!sphinx_pid && pid_active?(sphinx_pid) | ||
| 141 | end | ||
| 142 | |||
| 143 | def self.sphinx_pid | ||
| 144 | pid_file = ThinkingSphinx::Configuration.instance.pid_file | ||
| 145 | cat_command = 'cat' | ||
| 146 | return nil unless File.exists?(pid_file) | ||
| 147 | |||
| 148 | if microsoft? | ||
| 149 | pid_file.gsub!('/', '\\') | ||
| 150 | cat_command = 'type' | ||
| 151 | end | ||
| 152 | |||
| 153 | `#{cat_command} #{pid_file}`[/\d+/] | ||
| 154 | end | ||
| 155 | |||
| 156 | def self.pid_active?(pid) | ||
| 157 | return true if microsoft? | ||
| 158 | |||
| 159 | begin | ||
| 160 | # In JRuby this returns -1 if the process doesn't exist | ||
| 161 | Process.getpgid(pid.to_i) != -1 | ||
| 162 | rescue Exception => e | ||
| 163 | false | ||
| 164 | end | ||
| 165 | end | ||
| 166 | |||
| 167 | def self.microsoft? | ||
| 168 | RUBY_PLATFORM =~ /mswin/ | ||
| 169 | end | ||
| 170 | |||
| 171 | def self.jruby? | ||
| 172 | defined?(JRUBY_VERSION) | ||
| 173 | end | ||
| 174 | |||
| 175 | def self.mysql? | ||
| 176 | ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlAdapter" || ( | ||
| 177 | jruby? && ::ActiveRecord::Base.connection.config[:adapter] == "jdbcmysql" | ||
| 178 | ) | ||
| 179 | end | ||
| 180 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record.rb new file mode 100644 index 0000000..3e85b50 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record.rb | |||
| @@ -0,0 +1,260 @@ | |||
| 1 | require 'thinking_sphinx/active_record/delta' | ||
| 2 | require 'thinking_sphinx/active_record/search' | ||
| 3 | require 'thinking_sphinx/active_record/has_many_association' | ||
| 4 | |||
| 5 | module ThinkingSphinx | ||
| 6 | # Core additions to ActiveRecord models - define_index for creating indexes | ||
| 7 | # for models. If you want to interrogate the index objects created for the | ||
| 8 | # model, you can use the class-level accessor :sphinx_indexes. | ||
| 9 | # | ||
| 10 | module ActiveRecord | ||
| 11 | def self.included(base) | ||
| 12 | base.class_eval do | ||
| 13 | class_inheritable_array :sphinx_indexes, :sphinx_facets | ||
| 14 | class << self | ||
| 15 | # Allows creation of indexes for Sphinx. If you don't do this, there | ||
| 16 | # isn't much point trying to search (or using this plugin at all, | ||
| 17 | # really). | ||
| 18 | # | ||
| 19 | # An example or two: | ||
| 20 | # | ||
| 21 | # define_index | ||
| 22 | # indexes :id, :as => :model_id | ||
| 23 | # indexes name | ||
| 24 | # end | ||
| 25 | # | ||
| 26 | # You can also grab fields from associations - multiple levels deep | ||
| 27 | # if necessary. | ||
| 28 | # | ||
| 29 | # define_index do | ||
| 30 | # indexes tags.name, :as => :tag | ||
| 31 | # indexes articles.content | ||
| 32 | # indexes orders.line_items.product.name, :as => :product | ||
| 33 | # end | ||
| 34 | # | ||
| 35 | # And it will automatically concatenate multiple fields: | ||
| 36 | # | ||
| 37 | # define_index do | ||
| 38 | # indexes [author.first_name, author.last_name], :as => :author | ||
| 39 | # end | ||
| 40 | # | ||
| 41 | # The #indexes method is for fields - if you want attributes, use | ||
| 42 | # #has instead. All the same rules apply - but keep in mind that | ||
| 43 | # attributes are for sorting, grouping and filtering, not searching. | ||
| 44 | # | ||
| 45 | # define_index do | ||
| 46 | # # fields ... | ||
| 47 | # | ||
| 48 | # has created_at, updated_at | ||
| 49 | # end | ||
| 50 | # | ||
| 51 | # One last feature is the delta index. This requires the model to | ||
| 52 | # have a boolean field named 'delta', and is enabled as follows: | ||
| 53 | # | ||
| 54 | # define_index do | ||
| 55 | # # fields ... | ||
| 56 | # # attributes ... | ||
| 57 | # | ||
| 58 | # set_property :delta => true | ||
| 59 | # end | ||
| 60 | # | ||
| 61 | # Check out the more detailed documentation for each of these methods | ||
| 62 | # at ThinkingSphinx::Index::Builder. | ||
| 63 | # | ||
| 64 | def define_index(&block) | ||
| 65 | return unless ThinkingSphinx.define_indexes? | ||
| 66 | |||
| 67 | self.sphinx_indexes ||= [] | ||
| 68 | index = Index.new(self, &block) | ||
| 69 | |||
| 70 | self.sphinx_indexes << index | ||
| 71 | unless ThinkingSphinx.indexed_models.include?(self.name) | ||
| 72 | ThinkingSphinx.indexed_models << self.name | ||
| 73 | end | ||
| 74 | |||
| 75 | if index.delta? | ||
| 76 | before_save :toggle_delta | ||
| 77 | after_commit :index_delta | ||
| 78 | end | ||
| 79 | |||
| 80 | after_destroy :toggle_deleted | ||
| 81 | |||
| 82 | index | ||
| 83 | end | ||
| 84 | alias_method :sphinx_index, :define_index | ||
| 85 | |||
| 86 | def sphinx_index_options | ||
| 87 | sphinx_indexes.last.options | ||
| 88 | end | ||
| 89 | |||
| 90 | # Generate a unique CRC value for the model's name, to use to | ||
| 91 | # determine which Sphinx documents belong to which AR records. | ||
| 92 | # | ||
| 93 | # Really only written for internal use - but hey, if it's useful to | ||
| 94 | # you in some other way, awesome. | ||
| 95 | # | ||
| 96 | def to_crc32 | ||
| 97 | self.name.to_crc32 | ||
| 98 | end | ||
| 99 | |||
| 100 | def to_crc32s | ||
| 101 | (subclasses << self).collect { |klass| klass.to_crc32 } | ||
| 102 | end | ||
| 103 | |||
| 104 | def source_of_sphinx_index | ||
| 105 | possible_models = self.sphinx_indexes.collect { |index| index.model } | ||
| 106 | return self if possible_models.include?(self) | ||
| 107 | |||
| 108 | parent = self.superclass | ||
| 109 | while !possible_models.include?(parent) && parent != ::ActiveRecord::Base | ||
| 110 | parent = parent.superclass | ||
| 111 | end | ||
| 112 | |||
| 113 | return parent | ||
| 114 | end | ||
| 115 | |||
| 116 | def to_riddle(offset) | ||
| 117 | sphinx_database_adapter.setup | ||
| 118 | |||
| 119 | indexes = [to_riddle_for_core(offset)] | ||
| 120 | indexes << to_riddle_for_delta(offset) if sphinx_delta? | ||
| 121 | indexes << to_riddle_for_distributed | ||
| 122 | end | ||
| 123 | |||
| 124 | def sphinx_database_adapter | ||
| 125 | @sphinx_database_adapter ||= | ||
| 126 | ThinkingSphinx::AbstractAdapter.detect(self) | ||
| 127 | end | ||
| 128 | |||
| 129 | private | ||
| 130 | |||
| 131 | def sphinx_name | ||
| 132 | self.name.underscore.tr(':/\\', '_') | ||
| 133 | end | ||
| 134 | |||
| 135 | def sphinx_delta? | ||
| 136 | self.sphinx_indexes.any? { |index| index.delta? } | ||
| 137 | end | ||
| 138 | |||
| 139 | def to_riddle_for_core(offset) | ||
| 140 | index = Riddle::Configuration::Index.new("#{sphinx_name}_core") | ||
| 141 | index.path = File.join( | ||
| 142 | ThinkingSphinx::Configuration.instance.searchd_file_path, index.name | ||
| 143 | ) | ||
| 144 | |||
| 145 | set_configuration_options_for_indexes index | ||
| 146 | set_field_settings_for_indexes index | ||
| 147 | |||
| 148 | self.sphinx_indexes.select { |ts_index| | ||
| 149 | ts_index.model == self | ||
| 150 | }.each_with_index do |ts_index, i| | ||
| 151 | index.sources << ts_index.to_riddle_for_core(offset, i) | ||
| 152 | end | ||
| 153 | |||
| 154 | index | ||
| 155 | end | ||
| 156 | |||
| 157 | def to_riddle_for_delta(offset) | ||
| 158 | index = Riddle::Configuration::Index.new("#{sphinx_name}_delta") | ||
| 159 | index.parent = "#{sphinx_name}_core" | ||
| 160 | index.path = File.join(ThinkingSphinx::Configuration.instance.searchd_file_path, index.name) | ||
| 161 | |||
| 162 | self.sphinx_indexes.each_with_index do |ts_index, i| | ||
| 163 | index.sources << ts_index.to_riddle_for_delta(offset, i) if ts_index.delta? | ||
| 164 | end | ||
| 165 | |||
| 166 | index | ||
| 167 | end | ||
| 168 | |||
| 169 | def to_riddle_for_distributed | ||
| 170 | index = Riddle::Configuration::DistributedIndex.new(sphinx_name) | ||
| 171 | index.local_indexes << "#{sphinx_name}_core" | ||
| 172 | index.local_indexes.unshift "#{sphinx_name}_delta" if sphinx_delta? | ||
| 173 | index | ||
| 174 | end | ||
| 175 | |||
| 176 | def set_configuration_options_for_indexes(index) | ||
| 177 | ThinkingSphinx::Configuration.instance.index_options.each do |key, value| | ||
| 178 | index.send("#{key}=".to_sym, value) | ||
| 179 | end | ||
| 180 | |||
| 181 | self.sphinx_indexes.each do |ts_index| | ||
| 182 | ts_index.options.each do |key, value| | ||
| 183 | index.send("#{key}=".to_sym, value) if ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s) && !value.nil? | ||
| 184 | end | ||
| 185 | end | ||
| 186 | end | ||
| 187 | |||
| 188 | def set_field_settings_for_indexes(index) | ||
| 189 | field_names = lambda { |field| field.unique_name.to_s } | ||
| 190 | |||
| 191 | self.sphinx_indexes.each do |ts_index| | ||
| 192 | index.prefix_field_names += ts_index.prefix_fields.collect(&field_names) | ||
| 193 | index.infix_field_names += ts_index.infix_fields.collect(&field_names) | ||
| 194 | end | ||
| 195 | end | ||
| 196 | end | ||
| 197 | end | ||
| 198 | |||
| 199 | base.send(:include, ThinkingSphinx::ActiveRecord::Delta) | ||
| 200 | base.send(:include, ThinkingSphinx::ActiveRecord::Search) | ||
| 201 | |||
| 202 | ::ActiveRecord::Associations::HasManyAssociation.send( | ||
| 203 | :include, ThinkingSphinx::ActiveRecord::HasManyAssociation | ||
| 204 | ) | ||
| 205 | ::ActiveRecord::Associations::HasManyThroughAssociation.send( | ||
| 206 | :include, ThinkingSphinx::ActiveRecord::HasManyAssociation | ||
| 207 | ) | ||
| 208 | end | ||
| 209 | |||
| 210 | def in_index?(suffix) | ||
| 211 | self.class.search_for_id self.sphinx_document_id, sphinx_index_name(suffix) | ||
| 212 | end | ||
| 213 | |||
| 214 | def in_core_index? | ||
| 215 | in_index? "core" | ||
| 216 | end | ||
| 217 | |||
| 218 | def in_delta_index? | ||
| 219 | in_index? "delta" | ||
| 220 | end | ||
| 221 | |||
| 222 | def in_both_indexes? | ||
| 223 | in_core_index? && in_delta_index? | ||
| 224 | end | ||
| 225 | |||
| 226 | def toggle_deleted | ||
| 227 | return unless ThinkingSphinx.updates_enabled? && ThinkingSphinx.sphinx_running? | ||
| 228 | |||
| 229 | config = ThinkingSphinx::Configuration.instance | ||
| 230 | client = Riddle::Client.new config.address, config.port | ||
| 231 | |||
| 232 | client.update( | ||
| 233 | "#{self.class.sphinx_indexes.first.name}_core", | ||
| 234 | ['sphinx_deleted'], | ||
| 235 | {self.sphinx_document_id => 1} | ||
| 236 | ) if self.in_core_index? | ||
| 237 | |||
| 238 | client.update( | ||
| 239 | "#{self.class.sphinx_indexes.first.name}_delta", | ||
| 240 | ['sphinx_deleted'], | ||
| 241 | {self.sphinx_document_id => 1} | ||
| 242 | ) if ThinkingSphinx.deltas_enabled? && | ||
| 243 | self.class.sphinx_indexes.any? { |index| index.delta? } && | ||
| 244 | self.toggled_delta? | ||
| 245 | rescue ::ThinkingSphinx::ConnectionError | ||
| 246 | # nothing | ||
| 247 | end | ||
| 248 | |||
| 249 | def sphinx_document_id | ||
| 250 | (self.id * ThinkingSphinx.indexed_models.size) + | ||
| 251 | ThinkingSphinx.indexed_models.index(self.class.source_of_sphinx_index.name) | ||
| 252 | end | ||
| 253 | |||
| 254 | private | ||
| 255 | |||
| 256 | def sphinx_index_name(suffix) | ||
| 257 | "#{self.class.source_of_sphinx_index.name.underscore.tr(':/\\', '_')}_#{suffix}" | ||
| 258 | end | ||
| 259 | end | ||
| 260 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/delta.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/delta.rb new file mode 100644 index 0000000..f21aba2 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/delta.rb | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module ActiveRecord | ||
| 3 | # This module contains all the delta-related code for models. There isn't | ||
| 4 | # really anything you need to call manually in here - except perhaps | ||
| 5 | # index_delta, but not sure what reason why. | ||
| 6 | # | ||
| 7 | module Delta | ||
| 8 | # Code for after_commit callback is written by Eli Miller: | ||
| 9 | # http://elimiller.blogspot.com/2007/06/proper-cache-expiry-with-aftercommit.html | ||
| 10 | # with slight modification from Joost Hietbrink. | ||
| 11 | # | ||
| 12 | def self.included(base) | ||
| 13 | base.class_eval do | ||
| 14 | class << self | ||
| 15 | # Temporarily disable delta indexing inside a block, then perform a single | ||
| 16 | # rebuild of index at the end. | ||
| 17 | # | ||
| 18 | # Useful when performing updates to batches of models to prevent | ||
| 19 | # the delta index being rebuilt after each individual update. | ||
| 20 | # | ||
| 21 | # In the following example, the delta index will only be rebuilt once, | ||
| 22 | # not 10 times. | ||
| 23 | # | ||
| 24 | # SomeModel.suspended_delta do | ||
| 25 | # 10.times do | ||
| 26 | # SomeModel.create( ... ) | ||
| 27 | # end | ||
| 28 | # end | ||
| 29 | # | ||
| 30 | def suspended_delta(reindex_after = true, &block) | ||
| 31 | original_setting = ThinkingSphinx.deltas_enabled? | ||
| 32 | ThinkingSphinx.deltas_enabled = false | ||
| 33 | begin | ||
| 34 | yield | ||
| 35 | ensure | ||
| 36 | ThinkingSphinx.deltas_enabled = original_setting | ||
| 37 | self.index_delta if reindex_after | ||
| 38 | end | ||
| 39 | end | ||
| 40 | |||
| 41 | # Build the delta index for the related model. This won't be called | ||
| 42 | # if running in the test environment. | ||
| 43 | # | ||
| 44 | def index_delta(instance = nil) | ||
| 45 | delta_object.index(self, instance) | ||
| 46 | end | ||
| 47 | |||
| 48 | def delta_object | ||
| 49 | self.sphinx_indexes.first.delta_object | ||
| 50 | end | ||
| 51 | end | ||
| 52 | |||
| 53 | def toggled_delta? | ||
| 54 | self.class.delta_object.toggled(self) | ||
| 55 | end | ||
| 56 | |||
| 57 | private | ||
| 58 | |||
| 59 | # Set the delta value for the model to be true. | ||
| 60 | def toggle_delta | ||
| 61 | self.class.delta_object.toggle(self) if should_toggle_delta? | ||
| 62 | end | ||
| 63 | |||
| 64 | # Build the delta index for the related model. This won't be called | ||
| 65 | # if running in the test environment. | ||
| 66 | # | ||
| 67 | def index_delta | ||
| 68 | self.class.index_delta(self) if self.class.delta_object.toggled(self) | ||
| 69 | end | ||
| 70 | |||
| 71 | def should_toggle_delta? | ||
| 72 | !self.respond_to?(:changed?) || self.changed? || self.new_record? | ||
| 73 | end | ||
| 74 | end | ||
| 75 | end | ||
| 76 | end | ||
| 77 | end | ||
| 78 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/has_many_association.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/has_many_association.rb new file mode 100644 index 0000000..44b25c0 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/has_many_association.rb | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module ActiveRecord | ||
| 3 | module HasManyAssociation | ||
| 4 | def search(*args) | ||
| 5 | foreign_key = @reflection.primary_key_name | ||
| 6 | stack = [@reflection.options[:through]].compact | ||
| 7 | |||
| 8 | attribute = nil | ||
| 9 | (@reflection.klass.sphinx_indexes || []).each do |index| | ||
| 10 | attribute = index.attributes.detect { |attrib| | ||
| 11 | attrib.columns.length == 1 && | ||
| 12 | attrib.columns.first.__name == foreign_key.to_sym && | ||
| 13 | attrib.columns.first.__stack == stack | ||
| 14 | } | ||
| 15 | break if attribute | ||
| 16 | end | ||
| 17 | |||
| 18 | raise "Missing Attribute for Foreign Key #{foreign_key}" unless attribute | ||
| 19 | |||
| 20 | options = args.extract_options! | ||
| 21 | options[:with] ||= {} | ||
| 22 | options[:with][attribute.unique_name] = @owner.id | ||
| 23 | |||
| 24 | args << options | ||
| 25 | @reflection.klass.search(*args) | ||
| 26 | end | ||
| 27 | end | ||
| 28 | end | ||
| 29 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/search.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/search.rb new file mode 100644 index 0000000..fc3f2b4 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/active_record/search.rb | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module ActiveRecord | ||
| 3 | # This module covers the specific model searches - but the syntax is | ||
| 4 | # exactly the same as the core Search class - so use that as your refence | ||
| 5 | # point. | ||
| 6 | # | ||
| 7 | module Search | ||
| 8 | def self.included(base) | ||
| 9 | base.class_eval do | ||
| 10 | class << self | ||
| 11 | # Searches for results that match the parameters provided. Will only | ||
| 12 | # return the ids for the matching objects. See | ||
| 13 | # ThinkingSphinx::Search#search for syntax examples. | ||
| 14 | # | ||
| 15 | def search_for_ids(*args) | ||
| 16 | options = args.extract_options! | ||
| 17 | options[:class] = self | ||
| 18 | args << options | ||
| 19 | ThinkingSphinx::Search.search_for_ids(*args) | ||
| 20 | end | ||
| 21 | |||
| 22 | # Searches for results limited to a single model. See | ||
| 23 | # ThinkingSphinx::Search#search for syntax examples. | ||
| 24 | # | ||
| 25 | def search(*args) | ||
| 26 | options = args.extract_options! | ||
| 27 | options[:class] = self | ||
| 28 | args << options | ||
| 29 | ThinkingSphinx::Search.search(*args) | ||
| 30 | end | ||
| 31 | |||
| 32 | def search_count(*args) | ||
| 33 | options = args.extract_options! | ||
| 34 | options[:class] = self | ||
| 35 | args << options | ||
| 36 | ThinkingSphinx::Search.count(*args) | ||
| 37 | end | ||
| 38 | |||
| 39 | def search_for_id(*args) | ||
| 40 | options = args.extract_options! | ||
| 41 | options[:class] = self | ||
| 42 | args << options | ||
| 43 | ThinkingSphinx::Search.search_for_id(*args) | ||
| 44 | end | ||
| 45 | |||
| 46 | def facets(*args) | ||
| 47 | options = args.extract_options! | ||
| 48 | options[:class] = self | ||
| 49 | args << options | ||
| 50 | ThinkingSphinx::Search.facets(*args) | ||
| 51 | end | ||
| 52 | end | ||
| 53 | end | ||
| 54 | end | ||
| 55 | end | ||
| 56 | end | ||
| 57 | end \ No newline at end of file | ||
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 @@ | |||
| 1 | module 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 | ||
| 42 | end | ||
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 @@ | |||
| 1 | module 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 | ||
| 54 | end \ 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 @@ | |||
| 1 | module 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 | ||
| 130 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb new file mode 100644 index 0000000..b057035 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | # Association tracks a specific reflection and join to reference data that | ||
| 3 | # isn't in the base model. Very much an internal class for Thinking Sphinx - | ||
| 4 | # perhaps because I feel it's not as strong (or simple) as most of the rest. | ||
| 5 | # | ||
| 6 | class Association | ||
| 7 | attr_accessor :parent, :reflection, :join | ||
| 8 | |||
| 9 | # Create a new association by passing in the parent association, and the | ||
| 10 | # corresponding reflection instance. If there is no parent, pass in nil. | ||
| 11 | # | ||
| 12 | # top = Association.new nil, top_reflection | ||
| 13 | # child = Association.new top, child_reflection | ||
| 14 | # | ||
| 15 | def initialize(parent, reflection) | ||
| 16 | @parent, @reflection = parent, reflection | ||
| 17 | @children = {} | ||
| 18 | end | ||
| 19 | |||
| 20 | # Get the children associations for a given association name. The only time | ||
| 21 | # that there'll actually be more than one association is when the | ||
| 22 | # relationship is polymorphic. To keep things simple though, it will always | ||
| 23 | # be an Array that gets returned (an empty one if no matches). | ||
| 24 | # | ||
| 25 | # # where pages is an association on the class tied to the reflection. | ||
| 26 | # association.children(:pages) | ||
| 27 | # | ||
| 28 | def children(assoc) | ||
| 29 | @children[assoc] ||= Association.children(@reflection.klass, assoc, self) | ||
| 30 | end | ||
| 31 | |||
| 32 | # Get the children associations for a given class, association name and | ||
| 33 | # parent association. Much like the instance method of the same name, it | ||
| 34 | # will return an empty array if no associations have the name, and only | ||
| 35 | # have multiple association instances if the underlying relationship is | ||
| 36 | # polymorphic. | ||
| 37 | # | ||
| 38 | # Association.children(User, :pages, user_association) | ||
| 39 | # | ||
| 40 | def self.children(klass, assoc, parent=nil) | ||
| 41 | ref = klass.reflect_on_association(assoc) | ||
| 42 | |||
| 43 | return [] if ref.nil? | ||
| 44 | return [Association.new(parent, ref)] unless ref.options[:polymorphic] | ||
| 45 | |||
| 46 | # association is polymorphic - create associations for each | ||
| 47 | # non-polymorphic reflection. | ||
| 48 | polymorphic_classes(ref).collect { |klass| | ||
| 49 | Association.new parent, ::ActiveRecord::Reflection::AssociationReflection.new( | ||
| 50 | ref.macro, | ||
| 51 | "#{ref.name}_#{klass.name}".to_sym, | ||
| 52 | casted_options(klass, ref), | ||
| 53 | ref.active_record | ||
| 54 | ) | ||
| 55 | } | ||
| 56 | end | ||
| 57 | |||
| 58 | # Link up the join for this model from a base join - and set parent | ||
| 59 | # associations' joins recursively. | ||
| 60 | # | ||
| 61 | def join_to(base_join) | ||
| 62 | parent.join_to(base_join) if parent && parent.join.nil? | ||
| 63 | |||
| 64 | @join ||= ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.new( | ||
| 65 | @reflection, base_join, parent ? parent.join : base_join.joins.first | ||
| 66 | ) | ||
| 67 | end | ||
| 68 | |||
| 69 | # Returns the association's join SQL statements - and it replaces | ||
| 70 | # ::ts_join_alias:: with the aliased table name so the generated reflection | ||
| 71 | # join conditions avoid column name collisions. | ||
| 72 | # | ||
| 73 | def to_sql | ||
| 74 | @join.association_join.gsub(/::ts_join_alias::/, | ||
| 75 | "#{@reflection.klass.connection.quote_table_name(@join.parent.aliased_table_name)}" | ||
| 76 | ) | ||
| 77 | end | ||
| 78 | |||
| 79 | # Returns true if the association - or a parent - is a has_many or | ||
| 80 | # has_and_belongs_to_many. | ||
| 81 | # | ||
| 82 | def is_many? | ||
| 83 | case @reflection.macro | ||
| 84 | when :has_many, :has_and_belongs_to_many | ||
| 85 | true | ||
| 86 | else | ||
| 87 | @parent ? @parent.is_many? : false | ||
| 88 | end | ||
| 89 | end | ||
| 90 | |||
| 91 | # Returns an array of all the associations that lead to this one - starting | ||
| 92 | # with the top level all the way to the current association object. | ||
| 93 | # | ||
| 94 | def ancestors | ||
| 95 | (parent ? parent.ancestors : []) << self | ||
| 96 | end | ||
| 97 | |||
| 98 | def has_column?(column) | ||
| 99 | @reflection.klass.column_names.include?(column.to_s) | ||
| 100 | end | ||
| 101 | |||
| 102 | def primary_key_from_reflection | ||
| 103 | if @reflection.options[:through] | ||
| 104 | @reflection.source_reflection.options[:foreign_key] || | ||
| 105 | @reflection.source_reflection.primary_key_name | ||
| 106 | else | ||
| 107 | nil | ||
| 108 | end | ||
| 109 | end | ||
| 110 | |||
| 111 | def table | ||
| 112 | if @reflection.options[:through] | ||
| 113 | @join.aliased_join_table_name | ||
| 114 | else | ||
| 115 | @join.aliased_table_name | ||
| 116 | end | ||
| 117 | end | ||
| 118 | |||
| 119 | private | ||
| 120 | |||
| 121 | # Returns all the objects that could be currently instantiated from a | ||
| 122 | # polymorphic association. This is pretty damn fast if there's an index on | ||
| 123 | # the foreign type column - but if there isn't, it can take a while if you | ||
| 124 | # have a lot of data. | ||
| 125 | # | ||
| 126 | def self.polymorphic_classes(ref) | ||
| 127 | ref.active_record.connection.select_all( | ||
| 128 | "SELECT DISTINCT #{ref.options[:foreign_type]} " + | ||
| 129 | "FROM #{ref.active_record.table_name} " + | ||
| 130 | "WHERE #{ref.options[:foreign_type]} IS NOT NULL" | ||
| 131 | ).collect { |row| | ||
| 132 | row[ref.options[:foreign_type]].constantize | ||
| 133 | } | ||
| 134 | end | ||
| 135 | |||
| 136 | # Returns a new set of options for an association that mimics an existing | ||
| 137 | # polymorphic relationship for a specific class. It adds a condition to | ||
| 138 | # filter by the appropriate object. | ||
| 139 | # | ||
| 140 | def self.casted_options(klass, ref) | ||
| 141 | options = ref.options.clone | ||
| 142 | options[:polymorphic] = nil | ||
| 143 | options[:class_name] = klass.name | ||
| 144 | options[:foreign_key] ||= "#{ref.name}_id" | ||
| 145 | |||
| 146 | quoted_foreign_type = klass.connection.quote_column_name ref.options[:foreign_type] | ||
| 147 | case options[:conditions] | ||
| 148 | when nil | ||
| 149 | options[:conditions] = "::ts_join_alias::.#{quoted_foreign_type} = '#{klass.name}'" | ||
| 150 | when Array | ||
| 151 | options[:conditions] << "::ts_join_alias::.#{quoted_foreign_type} = '#{klass.name}'" | ||
| 152 | when Hash | ||
| 153 | options[:conditions].merge!(ref.options[:foreign_type] => klass.name) | ||
| 154 | else | ||
| 155 | options[:conditions] << " AND ::ts_join_alias::.#{quoted_foreign_type} = '#{klass.name}'" | ||
| 156 | end | ||
| 157 | |||
| 158 | options | ||
| 159 | end | ||
| 160 | end | ||
| 161 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/attribute.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/attribute.rb new file mode 100644 index 0000000..1d45b2e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/attribute.rb | |||
| @@ -0,0 +1,358 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | # Attributes - eternally useful when it comes to filtering, sorting or | ||
| 3 | # grouping. This class isn't really useful to you unless you're hacking | ||
| 4 | # around with the internals of Thinking Sphinx - but hey, don't let that | ||
| 5 | # stop you. | ||
| 6 | # | ||
| 7 | # One key thing to remember - if you're using the attribute manually to | ||
| 8 | # generate SQL statements, you'll need to set the base model, and all the | ||
| 9 | # associations. Which can get messy. Use Index.link!, it really helps. | ||
| 10 | # | ||
| 11 | class Attribute | ||
| 12 | attr_accessor :alias, :columns, :associations, :model, :faceted, :source | ||
| 13 | |||
| 14 | # To create a new attribute, you'll need to pass in either a single Column | ||
| 15 | # or an array of them, and some (optional) options. | ||
| 16 | # | ||
| 17 | # Valid options are: | ||
| 18 | # - :as => :alias_name | ||
| 19 | # - :type => :attribute_type | ||
| 20 | # - :source => :field, :query, :ranged_query | ||
| 21 | # | ||
| 22 | # Alias is only required in three circumstances: when there's | ||
| 23 | # another attribute or field with the same name, when the column name is | ||
| 24 | # 'id', or when there's more than one column. | ||
| 25 | # | ||
| 26 | # Type is not required, unless you want to force a column to be a certain | ||
| 27 | # type (but keep in mind the value will not be CASTed in the SQL | ||
| 28 | # statements). The only time you really need to use this is when the type | ||
| 29 | # can't be figured out by the column - ie: when not actually using a | ||
| 30 | # database column as your source. | ||
| 31 | # | ||
| 32 | # Source is only used for multi-value attributes (MVA). By default this will | ||
| 33 | # use a left-join and a group_concat to obtain the values. For better performance | ||
| 34 | # during indexing it can be beneficial to let Sphinx use a separate query to retrieve | ||
| 35 | # all document,value-pairs. | ||
| 36 | # Either :query or :ranged_query will enable this feature, where :ranged_query will cause | ||
| 37 | # the query to be executed incremental. | ||
| 38 | # | ||
| 39 | # Example usage: | ||
| 40 | # | ||
| 41 | # Attribute.new( | ||
| 42 | # Column.new(:created_at) | ||
| 43 | # ) | ||
| 44 | # | ||
| 45 | # Attribute.new( | ||
| 46 | # Column.new(:posts, :id), | ||
| 47 | # :as => :post_ids | ||
| 48 | # ) | ||
| 49 | # | ||
| 50 | # Attribute.new( | ||
| 51 | # Column.new(:posts, :id), | ||
| 52 | # :as => :post_ids, | ||
| 53 | # :source => :ranged_query | ||
| 54 | # ) | ||
| 55 | # | ||
| 56 | # Attribute.new( | ||
| 57 | # [Column.new(:pages, :id), Column.new(:articles, :id)], | ||
| 58 | # :as => :content_ids | ||
| 59 | # ) | ||
| 60 | # | ||
| 61 | # Attribute.new( | ||
| 62 | # Column.new("NOW()"), | ||
| 63 | # :as => :indexed_at, | ||
| 64 | # :type => :datetime | ||
| 65 | # ) | ||
| 66 | # | ||
| 67 | # If you're creating attributes for latitude and longitude, don't forget | ||
| 68 | # that Sphinx expects these values to be in radians. | ||
| 69 | # | ||
| 70 | def initialize(columns, options = {}) | ||
| 71 | @columns = Array(columns) | ||
| 72 | @associations = {} | ||
| 73 | |||
| 74 | raise "Cannot define a field with no columns. Maybe you are trying to index a field with a reserved name (id, name). You can fix this error by using a symbol rather than a bare name (:id instead of id)." if @columns.empty? || @columns.any? { |column| !column.respond_to?(:__stack) } | ||
| 75 | |||
| 76 | @alias = options[:as] | ||
| 77 | @type = options[:type] | ||
| 78 | @faceted = options[:facet] | ||
| 79 | @source = options[:source] | ||
| 80 | @crc = options[:crc] | ||
| 81 | |||
| 82 | @type ||= :multi unless @source.nil? | ||
| 83 | @type = :integer if @type == :string && @crc | ||
| 84 | end | ||
| 85 | |||
| 86 | # Get the part of the SELECT clause related to this attribute. Don't forget | ||
| 87 | # to set your model and associations first though. | ||
| 88 | # | ||
| 89 | # This will concatenate strings and arrays of integers, and convert | ||
| 90 | # datetimes to timestamps, as needed. | ||
| 91 | # | ||
| 92 | def to_select_sql | ||
| 93 | return nil unless include_as_association? | ||
| 94 | |||
| 95 | clause = @columns.collect { |column| | ||
| 96 | column_with_prefix(column) | ||
| 97 | }.join(', ') | ||
| 98 | |||
| 99 | separator = all_ints? ? ',' : ' ' | ||
| 100 | |||
| 101 | clause = adapter.concatenate(clause, separator) if concat_ws? | ||
| 102 | clause = adapter.group_concatenate(clause, separator) if is_many? | ||
| 103 | clause = adapter.cast_to_datetime(clause) if type == :datetime | ||
| 104 | clause = adapter.convert_nulls(clause) if type == :string | ||
| 105 | clause = adapter.crc(clause) if @crc | ||
| 106 | |||
| 107 | "#{clause} AS #{quote_column(unique_name)}" | ||
| 108 | end | ||
| 109 | |||
| 110 | # Get the part of the GROUP BY clause related to this attribute - if one is | ||
| 111 | # needed. If not, all you'll get back is nil. The latter will happen if | ||
| 112 | # there isn't actually a real column to get data from, or if there's | ||
| 113 | # multiple data values (read: a has_many or has_and_belongs_to_many | ||
| 114 | # association). | ||
| 115 | # | ||
| 116 | def to_group_sql | ||
| 117 | case | ||
| 118 | when is_many?, is_string?, ThinkingSphinx.use_group_by_shortcut? | ||
| 119 | nil | ||
| 120 | else | ||
| 121 | @columns.collect { |column| | ||
| 122 | column_with_prefix(column) | ||
| 123 | } | ||
| 124 | end | ||
| 125 | end | ||
| 126 | |||
| 127 | def type_to_config | ||
| 128 | { | ||
| 129 | :multi => :sql_attr_multi, | ||
| 130 | :datetime => :sql_attr_timestamp, | ||
| 131 | :string => :sql_attr_str2ordinal, | ||
| 132 | :float => :sql_attr_float, | ||
| 133 | :boolean => :sql_attr_bool, | ||
| 134 | :integer => :sql_attr_uint | ||
| 135 | }[type] | ||
| 136 | end | ||
| 137 | |||
| 138 | def include_as_association? | ||
| 139 | ! (type == :multi && (source == :query || source == :ranged_query)) | ||
| 140 | end | ||
| 141 | |||
| 142 | # Returns the configuration value that should be used for | ||
| 143 | # the attribute. | ||
| 144 | # Special case is the multi-valued attribute that needs some | ||
| 145 | # extra configuration. | ||
| 146 | # | ||
| 147 | def config_value(offset = nil) | ||
| 148 | if type == :multi | ||
| 149 | multi_config = include_as_association? ? "field" : | ||
| 150 | source_value(offset).gsub(/\n\s*/, " ") | ||
| 151 | "uint #{unique_name} from #{multi_config}" | ||
| 152 | else | ||
| 153 | unique_name | ||
| 154 | end | ||
| 155 | end | ||
| 156 | |||
| 157 | # Returns the unique name of the attribute - which is either the alias of | ||
| 158 | # the attribute, or the name of the only column - if there is only one. If | ||
| 159 | # there isn't, there should be an alias. Else things probably won't work. | ||
| 160 | # Consider yourself warned. | ||
| 161 | # | ||
| 162 | def unique_name | ||
| 163 | if @columns.length == 1 | ||
| 164 | @alias || @columns.first.__name | ||
| 165 | else | ||
| 166 | @alias | ||
| 167 | end | ||
| 168 | end | ||
| 169 | |||
| 170 | # Returns the type of the column. If that's not already set, it returns | ||
| 171 | # :multi if there's the possibility of more than one value, :string if | ||
| 172 | # there's more than one association, otherwise it figures out what the | ||
| 173 | # actual column's datatype is and returns that. | ||
| 174 | # | ||
| 175 | def type | ||
| 176 | @type ||= begin | ||
| 177 | base_type = case | ||
| 178 | when is_many?, is_many_ints? | ||
| 179 | :multi | ||
| 180 | when @associations.values.flatten.length > 1 | ||
| 181 | :string | ||
| 182 | else | ||
| 183 | translated_type_from_database | ||
| 184 | end | ||
| 185 | |||
| 186 | if base_type == :string && @crc | ||
| 187 | :integer | ||
| 188 | else | ||
| 189 | @crc = false | ||
| 190 | base_type | ||
| 191 | end | ||
| 192 | end | ||
| 193 | end | ||
| 194 | |||
| 195 | def to_facet | ||
| 196 | return nil unless @faceted | ||
| 197 | |||
| 198 | ThinkingSphinx::Facet.new(self) | ||
| 199 | end | ||
| 200 | |||
| 201 | private | ||
| 202 | |||
| 203 | def source_value(offset) | ||
| 204 | if is_string? | ||
| 205 | "#{source.to_s.dasherize}; #{columns.first.__name}" | ||
| 206 | elsif source == :ranged_query | ||
| 207 | "ranged-query; #{query offset} #{query_clause}; #{range_query}" | ||
| 208 | else | ||
| 209 | "query; #{query offset}" | ||
| 210 | end | ||
| 211 | end | ||
| 212 | |||
| 213 | def query(offset) | ||
| 214 | assoc = association_for_mva | ||
| 215 | raise "Could not determine SQL for MVA" if assoc.nil? | ||
| 216 | |||
| 217 | <<-SQL | ||
| 218 | SELECT #{foreign_key_for_mva assoc} | ||
| 219 | #{ThinkingSphinx.unique_id_expression(offset)} AS #{quote_column('id')}, | ||
| 220 | #{primary_key_for_mva(assoc)} AS #{quote_column(unique_name)} | ||
| 221 | FROM #{quote_table_name assoc.table} | ||
| 222 | SQL | ||
| 223 | end | ||
| 224 | |||
| 225 | def query_clause | ||
| 226 | foreign_key = foreign_key_for_mva association_for_mva | ||
| 227 | "WHERE #{foreign_key} >= $start AND #{foreign_key} <= $end" | ||
| 228 | end | ||
| 229 | |||
| 230 | def range_query | ||
| 231 | assoc = association_for_mva | ||
| 232 | foreign_key = foreign_key_for_mva assoc | ||
| 233 | "SELECT MIN(#{foreign_key}), MAX(#{foreign_key}) FROM #{quote_table_name assoc.table}" | ||
| 234 | end | ||
| 235 | |||
| 236 | def primary_key_for_mva(assoc) | ||
| 237 | quote_with_table( | ||
| 238 | assoc.table, assoc.primary_key_from_reflection || columns.first.__name | ||
| 239 | ) | ||
| 240 | end | ||
| 241 | |||
| 242 | def foreign_key_for_mva(assoc) | ||
| 243 | quote_with_table assoc.table, assoc.reflection.primary_key_name | ||
| 244 | end | ||
| 245 | |||
| 246 | def association_for_mva | ||
| 247 | @association_for_mva ||= associations[columns.first].detect { |assoc| | ||
| 248 | assoc.has_column?(columns.first.__name) | ||
| 249 | } | ||
| 250 | end | ||
| 251 | |||
| 252 | def adapter | ||
| 253 | @adapter ||= @model.sphinx_database_adapter | ||
| 254 | end | ||
| 255 | |||
| 256 | def quote_with_table(table, column) | ||
| 257 | "#{quote_table_name(table)}.#{quote_column(column)}" | ||
| 258 | end | ||
| 259 | |||
| 260 | def quote_column(column) | ||
| 261 | @model.connection.quote_column_name(column) | ||
| 262 | end | ||
| 263 | |||
| 264 | def quote_table_name(table_name) | ||
| 265 | @model.connection.quote_table_name(table_name) | ||
| 266 | end | ||
| 267 | |||
| 268 | # Indication of whether the columns should be concatenated with a space | ||
| 269 | # between each value. True if there's either multiple sources or multiple | ||
| 270 | # associations. | ||
| 271 | # | ||
| 272 | def concat_ws? | ||
| 273 | multiple_associations? || @columns.length > 1 | ||
| 274 | end | ||
| 275 | |||
| 276 | # Checks whether any column requires multiple associations (which only | ||
| 277 | # happens for polymorphic situations). | ||
| 278 | # | ||
| 279 | def multiple_associations? | ||
| 280 | associations.any? { |col,assocs| assocs.length > 1 } | ||
| 281 | end | ||
| 282 | |||
| 283 | # Builds a column reference tied to the appropriate associations. This | ||
| 284 | # dives into the associations hash and their corresponding joins to | ||
| 285 | # figure out how to correctly reference a column in SQL. | ||
| 286 | # | ||
| 287 | def column_with_prefix(column) | ||
| 288 | if column.is_string? | ||
| 289 | column.__name | ||
| 290 | elsif associations[column].empty? | ||
| 291 | "#{@model.quoted_table_name}.#{quote_column(column.__name)}" | ||
| 292 | else | ||
| 293 | associations[column].collect { |assoc| | ||
| 294 | assoc.has_column?(column.__name) ? | ||
| 295 | "#{quote_table_name(assoc.join.aliased_table_name)}" + | ||
| 296 | ".#{quote_column(column.__name)}" : | ||
| 297 | nil | ||
| 298 | }.compact.join(', ') | ||
| 299 | end | ||
| 300 | end | ||
| 301 | |||
| 302 | # Could there be more than one value related to the parent record? If so, | ||
| 303 | # then this will return true. If not, false. It's that simple. | ||
| 304 | # | ||
| 305 | def is_many? | ||
| 306 | associations.values.flatten.any? { |assoc| assoc.is_many? } | ||
| 307 | end | ||
| 308 | |||
| 309 | def is_many_ints? | ||
| 310 | concat_ws? && all_ints? | ||
| 311 | end | ||
| 312 | |||
| 313 | # Returns true if any of the columns are string values, instead of database | ||
| 314 | # column references. | ||
| 315 | def is_string? | ||
| 316 | columns.all? { |col| col.is_string? } | ||
| 317 | end | ||
| 318 | |||
| 319 | def all_ints? | ||
| 320 | @columns.all? { |col| | ||
| 321 | klasses = @associations[col].empty? ? [@model] : | ||
| 322 | @associations[col].collect { |assoc| assoc.reflection.klass } | ||
| 323 | klasses.all? { |klass| | ||
| 324 | column = klass.columns.detect { |column| column.name == col.__name.to_s } | ||
| 325 | !column.nil? && column.type == :integer | ||
| 326 | } | ||
| 327 | } | ||
| 328 | end | ||
| 329 | |||
| 330 | def type_from_database | ||
| 331 | klass = @associations.values.flatten.first ? | ||
| 332 | @associations.values.flatten.first.reflection.klass : @model | ||
| 333 | |||
| 334 | klass.columns.detect { |col| | ||
| 335 | @columns.collect { |c| c.__name.to_s }.include? col.name | ||
| 336 | }.type | ||
| 337 | end | ||
| 338 | |||
| 339 | def translated_type_from_database | ||
| 340 | case type_from_db = type_from_database | ||
| 341 | when :datetime, :string, :float, :boolean, :integer | ||
| 342 | type_from_db | ||
| 343 | when :decimal | ||
| 344 | :float | ||
| 345 | when :timestamp, :date | ||
| 346 | :datetime | ||
| 347 | else | ||
| 348 | raise <<-MESSAGE | ||
| 349 | |||
| 350 | Cannot automatically map column type #{type_from_db} to an equivalent Sphinx | ||
| 351 | type (integer, float, boolean, datetime, string as ordinal). You could try to | ||
| 352 | explicitly convert the column's value in your define_index block: | ||
| 353 | has "CAST(column AS INT)", :type => :integer, :as => :column | ||
| 354 | MESSAGE | ||
| 355 | end | ||
| 356 | end | ||
| 357 | end | ||
| 358 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/class_facet.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/class_facet.rb new file mode 100644 index 0000000..cb301b8 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/class_facet.rb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | class ClassFacet < ThinkingSphinx::Facet | ||
| 3 | def name | ||
| 4 | :class | ||
| 5 | end | ||
| 6 | |||
| 7 | def attribute_name | ||
| 8 | "class_crc" | ||
| 9 | end | ||
| 10 | |||
| 11 | def value(object, attribute_value) | ||
| 12 | object.class.name | ||
| 13 | end | ||
| 14 | end | ||
| 15 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/collection.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/collection.rb new file mode 100644 index 0000000..406c2ae --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/collection.rb | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | class Collection < ::Array | ||
| 3 | attr_reader :total_entries, :total_pages, :current_page, :per_page | ||
| 4 | attr_accessor :results | ||
| 5 | |||
| 6 | # Compatibility with older versions of will_paginate | ||
| 7 | alias_method :page_count, :total_pages | ||
| 8 | |||
| 9 | def initialize(page, per_page, entries, total_entries) | ||
| 10 | @current_page, @per_page, @total_entries = page, per_page, total_entries | ||
| 11 | |||
| 12 | @total_pages = (entries / @per_page.to_f).ceil | ||
| 13 | end | ||
| 14 | |||
| 15 | def self.ids_from_results(results, page, limit, options) | ||
| 16 | collection = self.new(page, limit, | ||
| 17 | results[:total] || 0, results[:total_found] || 0 | ||
| 18 | ) | ||
| 19 | collection.results = results | ||
| 20 | collection.replace results[:matches].collect { |match| | ||
| 21 | match[:attributes]["sphinx_internal_id"] | ||
| 22 | } | ||
| 23 | return collection | ||
| 24 | end | ||
| 25 | |||
| 26 | def self.create_from_results(results, page, limit, options) | ||
| 27 | collection = self.new(page, limit, | ||
| 28 | results[:total] || 0, results[:total_found] || 0 | ||
| 29 | ) | ||
| 30 | collection.results = results | ||
| 31 | collection.replace instances_from_matches(results[:matches], options) | ||
| 32 | return collection | ||
| 33 | end | ||
| 34 | |||
| 35 | def self.instances_from_matches(matches, options = {}) | ||
| 36 | if klass = options[:class] | ||
| 37 | instances_from_class klass, matches, options | ||
| 38 | else | ||
| 39 | instances_from_classes matches, options | ||
| 40 | end | ||
| 41 | end | ||
| 42 | |||
| 43 | def self.instances_from_class(klass, matches, options = {}) | ||
| 44 | index_options = klass.sphinx_index_options | ||
| 45 | |||
| 46 | ids = matches.collect { |match| match[:attributes]["sphinx_internal_id"] } | ||
| 47 | instances = ids.length > 0 ? klass.find( | ||
| 48 | :all, | ||
| 49 | :conditions => {klass.primary_key.to_sym => ids}, | ||
| 50 | :include => (options[:include] || index_options[:include]), | ||
| 51 | :select => (options[:select] || index_options[:select]), | ||
| 52 | :order => (options[:sql_order] || index_options[:sql_order]) | ||
| 53 | ) : [] | ||
| 54 | |||
| 55 | # Raise an exception if we find records in Sphinx but not in the DB, so | ||
| 56 | # the search method can retry without them. See | ||
| 57 | # ThinkingSphinx::Search.retry_search_on_stale_index. | ||
| 58 | if options[:raise_on_stale] && instances.length < ids.length | ||
| 59 | stale_ids = ids - instances.map {|i| i.id } | ||
| 60 | raise StaleIdsException, stale_ids | ||
| 61 | end | ||
| 62 | |||
| 63 | # if the user has specified an SQL order, return the collection | ||
| 64 | # without rearranging it into the Sphinx order | ||
| 65 | return instances if options[:sql_order] | ||
| 66 | |||
| 67 | ids.collect { |obj_id| | ||
| 68 | instances.detect { |obj| obj.id == obj_id } | ||
| 69 | } | ||
| 70 | end | ||
| 71 | |||
| 72 | # Group results by class and call #find(:all) once for each group to reduce | ||
| 73 | # the number of #find's in multi-model searches. | ||
| 74 | # | ||
| 75 | def self.instances_from_classes(matches, options = {}) | ||
| 76 | groups = matches.group_by { |match| match[:attributes]["class_crc"] } | ||
| 77 | groups.each do |crc, group| | ||
| 78 | group.replace( | ||
| 79 | instances_from_class(class_from_crc(crc), group, options) | ||
| 80 | ) | ||
| 81 | end | ||
| 82 | |||
| 83 | matches.collect do |match| | ||
| 84 | groups.detect { |crc, group| | ||
| 85 | crc == match[:attributes]["class_crc"] | ||
| 86 | }[1].detect { |obj| | ||
| 87 | obj.id == match[:attributes]["sphinx_internal_id"] | ||
| 88 | } | ||
| 89 | end | ||
| 90 | end | ||
| 91 | |||
| 92 | def self.class_from_crc(crc) | ||
| 93 | @@models_by_crc ||= ThinkingSphinx.indexed_models.inject({}) do |hash, model| | ||
| 94 | hash[model.constantize.to_crc32] = model | ||
| 95 | model.constantize.subclasses.each { |subclass| | ||
| 96 | hash[subclass.to_crc32] = subclass.name | ||
| 97 | } | ||
| 98 | hash | ||
| 99 | end | ||
| 100 | @@models_by_crc[crc].constantize | ||
| 101 | end | ||
| 102 | |||
| 103 | def previous_page | ||
| 104 | current_page > 1 ? (current_page - 1) : nil | ||
| 105 | end | ||
| 106 | |||
| 107 | def next_page | ||
| 108 | current_page < total_pages ? (current_page + 1): nil | ||
| 109 | end | ||
| 110 | |||
| 111 | def offset | ||
| 112 | (current_page - 1) * @per_page | ||
| 113 | end | ||
| 114 | |||
| 115 | def method_missing(method, *args, &block) | ||
| 116 | super unless method.to_s[/^each_with_.*/] | ||
| 117 | |||
| 118 | each_with_attribute method.to_s.gsub(/^each_with_/, ''), &block | ||
| 119 | end | ||
| 120 | |||
| 121 | def each_with_groupby_and_count(&block) | ||
| 122 | results[:matches].each_with_index do |match, index| | ||
| 123 | yield self[index], match[:attributes]["@groupby"], match[:attributes]["@count"] | ||
| 124 | end | ||
| 125 | end | ||
| 126 | |||
| 127 | def each_with_attribute(attribute, &block) | ||
| 128 | results[:matches].each_with_index do |match, index| | ||
| 129 | yield self[index], (match[:attributes][attribute] || match[:attributes]["@#{attribute}"]) | ||
| 130 | end | ||
| 131 | end | ||
| 132 | |||
| 133 | def each_with_weighting(&block) | ||
| 134 | results[:matches].each_with_index do |match, index| | ||
| 135 | yield self[index], match[:weight] | ||
| 136 | end | ||
| 137 | end | ||
| 138 | |||
| 139 | def inject_with_groupby_and_count(initial = nil, &block) | ||
| 140 | index = -1 | ||
| 141 | results[:matches].inject(initial) do |memo, match| | ||
| 142 | index += 1 | ||
| 143 | yield memo, self[index], match[:attributes]["@groupby"], match[:attributes]["@count"] | ||
| 144 | end | ||
| 145 | end | ||
| 146 | end | ||
| 147 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/configuration.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/configuration.rb new file mode 100644 index 0000000..31543f5 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/configuration.rb | |||
| @@ -0,0 +1,237 @@ | |||
| 1 | require 'erb' | ||
| 2 | require 'singleton' | ||
| 3 | |||
| 4 | module ThinkingSphinx | ||
| 5 | # This class both keeps track of the configuration settings for Sphinx and | ||
| 6 | # also generates the resulting file for Sphinx to use. | ||
| 7 | # | ||
| 8 | # Here are the default settings, relative to RAILS_ROOT where relevant: | ||
| 9 | # | ||
| 10 | # config file:: config/#{environment}.sphinx.conf | ||
| 11 | # searchd log file:: log/searchd.log | ||
| 12 | # query log file:: log/searchd.query.log | ||
| 13 | # pid file:: log/searchd.#{environment}.pid | ||
| 14 | # searchd files:: db/sphinx/#{environment}/ | ||
| 15 | # address:: 127.0.0.1 | ||
| 16 | # port:: 3312 | ||
| 17 | # allow star:: false | ||
| 18 | # min prefix length:: 1 | ||
| 19 | # min infix length:: 1 | ||
| 20 | # mem limit:: 64M | ||
| 21 | # max matches:: 1000 | ||
| 22 | # morphology:: stem_en | ||
| 23 | # charset type:: utf-8 | ||
| 24 | # charset table:: nil | ||
| 25 | # ignore chars:: nil | ||
| 26 | # html strip:: false | ||
| 27 | # html remove elements:: '' | ||
| 28 | # | ||
| 29 | # If you want to change these settings, create a YAML file at | ||
| 30 | # config/sphinx.yml with settings for each environment, in a similar | ||
| 31 | # fashion to database.yml - using the following keys: config_file, | ||
| 32 | # searchd_log_file, query_log_file, pid_file, searchd_file_path, port, | ||
| 33 | # allow_star, enable_star, min_prefix_len, min_infix_len, mem_limit, | ||
| 34 | # max_matches, # morphology, charset_type, charset_table, ignore_chars, | ||
| 35 | # html_strip, # html_remove_elements. I think you've got the idea. | ||
| 36 | # | ||
| 37 | # Each setting in the YAML file is optional - so only put in the ones you | ||
| 38 | # want to change. | ||
| 39 | # | ||
| 40 | # Keep in mind, if for some particular reason you're using a version of | ||
| 41 | # Sphinx older than 0.9.8 r871 (that's prior to the proper 0.9.8 release), | ||
| 42 | # don't set allow_star to true. | ||
| 43 | # | ||
| 44 | class Configuration | ||
| 45 | include Singleton | ||
| 46 | |||
| 47 | SourceOptions = %w( mysql_connect_flags sql_range_step sql_query_pre | ||
| 48 | sql_query_post sql_ranged_throttle sql_query_post_index ) | ||
| 49 | |||
| 50 | IndexOptions = %w( charset_table charset_type docinfo enable_star | ||
| 51 | exceptions html_index_attrs html_remove_elements html_strip ignore_chars | ||
| 52 | min_infix_len min_prefix_len min_word_len mlock morphology ngram_chars | ||
| 53 | ngram_len phrase_boundary phrase_boundary_step preopen stopwords | ||
| 54 | wordforms ) | ||
| 55 | |||
| 56 | attr_accessor :config_file, :searchd_log_file, :query_log_file, | ||
| 57 | :pid_file, :searchd_file_path, :address, :port, :allow_star, | ||
| 58 | :database_yml_file, :app_root, :bin_path, :model_directories | ||
| 59 | |||
| 60 | attr_accessor :source_options, :index_options | ||
| 61 | |||
| 62 | attr_reader :environment, :configuration | ||
| 63 | |||
| 64 | # Load in the configuration settings - this will look for config/sphinx.yml | ||
| 65 | # and parse it according to the current environment. | ||
| 66 | # | ||
| 67 | def initialize(app_root = Dir.pwd) | ||
| 68 | self.reset | ||
| 69 | end | ||
| 70 | |||
| 71 | def reset | ||
| 72 | self.app_root = RAILS_ROOT if defined?(RAILS_ROOT) | ||
| 73 | self.app_root = Merb.root if defined?(Merb) | ||
| 74 | self.app_root ||= app_root | ||
| 75 | |||
| 76 | @configuration = Riddle::Configuration.new | ||
| 77 | @configuration.searchd.address = "127.0.0.1" | ||
| 78 | @configuration.searchd.port = 3312 | ||
| 79 | @configuration.searchd.pid_file = "#{self.app_root}/log/searchd.#{environment}.pid" | ||
| 80 | @configuration.searchd.log = "#{self.app_root}/log/searchd.log" | ||
| 81 | @configuration.searchd.query_log = "#{self.app_root}/log/searchd.query.log" | ||
| 82 | |||
| 83 | self.database_yml_file = "#{self.app_root}/config/database.yml" | ||
| 84 | self.config_file = "#{self.app_root}/config/#{environment}.sphinx.conf" | ||
| 85 | self.searchd_file_path = "#{self.app_root}/db/sphinx/#{environment}" | ||
| 86 | self.allow_star = false | ||
| 87 | self.bin_path = "" | ||
| 88 | self.model_directories = ["#{app_root}/app/models/"] + | ||
| 89 | Dir.glob("#{app_root}/vendor/plugins/*/app/models/") | ||
| 90 | |||
| 91 | self.source_options = {} | ||
| 92 | self.index_options = { | ||
| 93 | :charset_type => "utf-8", | ||
| 94 | :morphology => "stem_en" | ||
| 95 | } | ||
| 96 | |||
| 97 | parse_config | ||
| 98 | |||
| 99 | self | ||
| 100 | end | ||
| 101 | |||
| 102 | def self.environment | ||
| 103 | @@environment ||= ( | ||
| 104 | defined?(Merb) ? Merb.environment : ENV['RAILS_ENV'] | ||
| 105 | ) || "development" | ||
| 106 | end | ||
| 107 | |||
| 108 | def environment | ||
| 109 | self.class.environment | ||
| 110 | end | ||
| 111 | |||
| 112 | def controller | ||
| 113 | @controller ||= Riddle::Controller.new(@configuration, self.config_file) | ||
| 114 | end | ||
| 115 | |||
| 116 | # Generate the config file for Sphinx by using all the settings defined and | ||
| 117 | # looping through all the models with indexes to build the relevant | ||
| 118 | # indexer and searchd configuration, and sources and indexes details. | ||
| 119 | # | ||
| 120 | def build(file_path=nil) | ||
| 121 | load_models | ||
| 122 | file_path ||= "#{self.config_file}" | ||
| 123 | |||
| 124 | @configuration.indexes.clear | ||
| 125 | |||
| 126 | ThinkingSphinx.indexed_models.each_with_index do |model, model_index| | ||
| 127 | @configuration.indexes.concat model.constantize.to_riddle(model_index) | ||
| 128 | end | ||
| 129 | |||
| 130 | open(file_path, "w") do |file| | ||
| 131 | file.write @configuration.render | ||
| 132 | end | ||
| 133 | end | ||
| 134 | |||
| 135 | # Make sure all models are loaded - without reloading any that | ||
| 136 | # ActiveRecord::Base is already aware of (otherwise we start to hit some | ||
| 137 | # messy dependencies issues). | ||
| 138 | # | ||
| 139 | def load_models | ||
| 140 | self.model_directories.each do |base| | ||
| 141 | Dir["#{base}**/*.rb"].each do |file| | ||
| 142 | model_name = file.gsub(/^#{base}([\w_\/\\]+)\.rb/, '\1') | ||
| 143 | |||
| 144 | next if model_name.nil? | ||
| 145 | next if ::ActiveRecord::Base.send(:subclasses).detect { |model| | ||
| 146 | model.name == model_name | ||
| 147 | } | ||
| 148 | |||
| 149 | begin | ||
| 150 | model_name.camelize.constantize | ||
| 151 | rescue LoadError | ||
| 152 | model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry | ||
| 153 | rescue NameError | ||
| 154 | next | ||
| 155 | end | ||
| 156 | end | ||
| 157 | end | ||
| 158 | end | ||
| 159 | |||
| 160 | def address | ||
| 161 | @configuration.searchd.address | ||
| 162 | end | ||
| 163 | |||
| 164 | def address=(address) | ||
| 165 | @configuration.searchd.address = address | ||
| 166 | end | ||
| 167 | |||
| 168 | def port | ||
| 169 | @configuration.searchd.port | ||
| 170 | end | ||
| 171 | |||
| 172 | def port=(port) | ||
| 173 | @configuration.searchd.port = port | ||
| 174 | end | ||
| 175 | |||
| 176 | def pid_file | ||
| 177 | @configuration.searchd.pid_file | ||
| 178 | end | ||
| 179 | |||
| 180 | def pid_file=(pid_file) | ||
| 181 | @configuration.searchd.pid_file = pid_file | ||
| 182 | end | ||
| 183 | |||
| 184 | def searchd_log_file | ||
| 185 | @configuration.searchd.log | ||
| 186 | end | ||
| 187 | |||
| 188 | def searchd_log_file=(file) | ||
| 189 | @configuration.searchd.log = file | ||
| 190 | end | ||
| 191 | |||
| 192 | def query_log_file | ||
| 193 | @configuration.searchd.query_log | ||
| 194 | end | ||
| 195 | |||
| 196 | def query_log_file=(file) | ||
| 197 | @configuration.searchd.query_log = file | ||
| 198 | end | ||
| 199 | |||
| 200 | private | ||
| 201 | |||
| 202 | # Parse the config/sphinx.yml file - if it exists - then use the attribute | ||
| 203 | # accessors to set the appropriate values. Nothing too clever. | ||
| 204 | # | ||
| 205 | def parse_config | ||
| 206 | path = "#{app_root}/config/sphinx.yml" | ||
| 207 | return unless File.exists?(path) | ||
| 208 | |||
| 209 | conf = YAML::load(ERB.new(IO.read(path)).result)[environment] | ||
| 210 | |||
| 211 | conf.each do |key,value| | ||
| 212 | self.send("#{key}=", value) if self.methods.include?("#{key}=") | ||
| 213 | |||
| 214 | set_sphinx_setting self.source_options, key, value, SourceOptions | ||
| 215 | set_sphinx_setting self.index_options, key, value, IndexOptions | ||
| 216 | set_sphinx_setting @configuration.searchd, key, value | ||
| 217 | set_sphinx_setting @configuration.indexer, key, value | ||
| 218 | end unless conf.nil? | ||
| 219 | |||
| 220 | self.bin_path += '/' unless self.bin_path.blank? | ||
| 221 | |||
| 222 | if self.allow_star | ||
| 223 | self.index_options[:enable_star] = true | ||
| 224 | self.index_options[:min_prefix_len] = 1 | ||
| 225 | end | ||
| 226 | end | ||
| 227 | |||
| 228 | def set_sphinx_setting(object, key, value, allowed = {}) | ||
| 229 | if object.is_a?(Hash) | ||
| 230 | object[key.to_sym] = value if allowed.include?(key.to_s) | ||
| 231 | else | ||
| 232 | object.send("#{key}=", value) if object.methods.include?("#{key}") | ||
| 233 | send("#{key}=", value) if self.methods.include?("#{key}") | ||
| 234 | end | ||
| 235 | end | ||
| 236 | end | ||
| 237 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/core/string.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/core/string.rb new file mode 100644 index 0000000..7ab3e62 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/core/string.rb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | require 'zlib' | ||
| 2 | |||
| 3 | module ThinkingSphinx | ||
| 4 | module Core | ||
| 5 | module String | ||
| 6 | def to_crc32 | ||
| 7 | Zlib.crc32 self | ||
| 8 | end | ||
| 9 | end | ||
| 10 | end | ||
| 11 | end | ||
| 12 | |||
| 13 | class String | ||
| 14 | include ThinkingSphinx::Core::String | ||
| 15 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas.rb new file mode 100644 index 0000000..57c396e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas.rb | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | require 'thinking_sphinx/deltas/default_delta' | ||
| 2 | require 'thinking_sphinx/deltas/delayed_delta' | ||
| 3 | require 'thinking_sphinx/deltas/datetime_delta' | ||
| 4 | |||
| 5 | module ThinkingSphinx | ||
| 6 | module Deltas | ||
| 7 | def self.parse(index, options) | ||
| 8 | delta_option = options.delete(:delta) | ||
| 9 | case delta_option | ||
| 10 | when TrueClass, :default | ||
| 11 | DefaultDelta.new index, options | ||
| 12 | when :delayed | ||
| 13 | DelayedDelta.new index, options | ||
| 14 | when :datetime | ||
| 15 | DatetimeDelta.new index, options | ||
| 16 | when FalseClass, nil | ||
| 17 | nil | ||
| 18 | else | ||
| 19 | if delta_option.ancestors.include?(ThinkingSphinx::Deltas::DefaultDelta) | ||
| 20 | delta_option.new index, options | ||
| 21 | else | ||
| 22 | raise "Unknown delta type" | ||
| 23 | end | ||
| 24 | end | ||
| 25 | end | ||
| 26 | end | ||
| 27 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/datetime_delta.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/datetime_delta.rb new file mode 100644 index 0000000..2ee46d4 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/datetime_delta.rb | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module Deltas | ||
| 3 | class DatetimeDelta < ThinkingSphinx::Deltas::DefaultDelta | ||
| 4 | attr_accessor :column, :threshold | ||
| 5 | |||
| 6 | def initialize(index, options) | ||
| 7 | @index = index | ||
| 8 | @column = options.delete(:delta_column) || :updated_at | ||
| 9 | @threshold = options.delete(:threshold) || 1.day | ||
| 10 | end | ||
| 11 | |||
| 12 | def index(model, instance = nil) | ||
| 13 | # do nothing | ||
| 14 | true | ||
| 15 | end | ||
| 16 | |||
| 17 | def delayed_index(model) | ||
| 18 | config = ThinkingSphinx::Configuration.instance | ||
| 19 | rotate = ThinkingSphinx.sphinx_running? ? "--rotate" : "" | ||
| 20 | |||
| 21 | output = `#{config.bin_path}indexer --config #{config.config_file} #{rotate} #{delta_index_name model}` | ||
| 22 | output += `#{config.bin_path}indexer --config #{config.config_file} #{rotate} --merge #{core_index_name model} #{delta_index_name model} --merge-dst-range sphinx_deleted 0 0` | ||
| 23 | puts output unless ThinkingSphinx.suppress_delta_output? | ||
| 24 | |||
| 25 | true | ||
| 26 | end | ||
| 27 | |||
| 28 | def toggle(instance) | ||
| 29 | # do nothing | ||
| 30 | end | ||
| 31 | |||
| 32 | def toggled(instance) | ||
| 33 | instance.send(@column) > @threshold.ago | ||
| 34 | end | ||
| 35 | |||
| 36 | def reset_query(model) | ||
| 37 | nil | ||
| 38 | end | ||
| 39 | |||
| 40 | def clause(model, toggled) | ||
| 41 | if toggled | ||
| 42 | "#{model.quoted_table_name}.#{@index.quote_column(@column.to_s)}" + | ||
| 43 | " > #{adapter.time_difference(@threshold)}" | ||
| 44 | else | ||
| 45 | nil | ||
| 46 | end | ||
| 47 | end | ||
| 48 | end | ||
| 49 | end | ||
| 50 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/default_delta.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/default_delta.rb new file mode 100644 index 0000000..c973612 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/default_delta.rb | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module Deltas | ||
| 3 | class DefaultDelta | ||
| 4 | attr_accessor :column | ||
| 5 | |||
| 6 | def initialize(index, options) | ||
| 7 | @index = index | ||
| 8 | @column = options.delete(:delta_column) || :delta | ||
| 9 | end | ||
| 10 | |||
| 11 | def index(model, instance = nil) | ||
| 12 | return true unless ThinkingSphinx.updates_enabled? && | ||
| 13 | ThinkingSphinx.deltas_enabled? | ||
| 14 | return true if instance && !toggled(instance) | ||
| 15 | |||
| 16 | config = ThinkingSphinx::Configuration.instance | ||
| 17 | client = Riddle::Client.new config.address, config.port | ||
| 18 | rotate = ThinkingSphinx.sphinx_running? ? "--rotate" : "" | ||
| 19 | |||
| 20 | output = `#{config.bin_path}indexer --config #{config.config_file} #{rotate} #{delta_index_name model}` | ||
| 21 | puts(output) unless ThinkingSphinx.suppress_delta_output? | ||
| 22 | |||
| 23 | client.update( | ||
| 24 | core_index_name(model), | ||
| 25 | ['sphinx_deleted'], | ||
| 26 | {instance.sphinx_document_id => [1]} | ||
| 27 | ) if instance && ThinkingSphinx.sphinx_running? && instance.in_both_indexes? | ||
| 28 | |||
| 29 | true | ||
| 30 | end | ||
| 31 | |||
| 32 | def toggle(instance) | ||
| 33 | instance.delta = true | ||
| 34 | end | ||
| 35 | |||
| 36 | def toggled(instance) | ||
| 37 | instance.delta | ||
| 38 | end | ||
| 39 | |||
| 40 | def reset_query(model) | ||
| 41 | "UPDATE #{model.quoted_table_name} SET " + | ||
| 42 | "#{@index.quote_column(@column.to_s)} = #{adapter.boolean(false)}" | ||
| 43 | end | ||
| 44 | |||
| 45 | def clause(model, toggled) | ||
| 46 | "#{model.quoted_table_name}.#{@index.quote_column(@column.to_s)}" + | ||
| 47 | " = #{adapter.boolean(toggled)}" | ||
| 48 | end | ||
| 49 | |||
| 50 | protected | ||
| 51 | |||
| 52 | def core_index_name(model) | ||
| 53 | "#{model.source_of_sphinx_index.name.underscore.tr(':/\\', '_')}_core" | ||
| 54 | end | ||
| 55 | |||
| 56 | def delta_index_name(model) | ||
| 57 | "#{model.source_of_sphinx_index.name.underscore.tr(':/\\', '_')}_delta" | ||
| 58 | end | ||
| 59 | |||
| 60 | private | ||
| 61 | |||
| 62 | def adapter | ||
| 63 | @adapter = @index.model.sphinx_database_adapter | ||
| 64 | end | ||
| 65 | end | ||
| 66 | end | ||
| 67 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta.rb new file mode 100644 index 0000000..e95298b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta.rb | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | require 'delayed/job' | ||
| 2 | |||
| 3 | require 'thinking_sphinx/deltas/delayed_delta/delta_job' | ||
| 4 | require 'thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job' | ||
| 5 | require 'thinking_sphinx/deltas/delayed_delta/job' | ||
| 6 | |||
| 7 | module ThinkingSphinx | ||
| 8 | module Deltas | ||
| 9 | class DelayedDelta < ThinkingSphinx::Deltas::DefaultDelta | ||
| 10 | def index(model, instance = nil) | ||
| 11 | ThinkingSphinx::Deltas::Job.enqueue( | ||
| 12 | ThinkingSphinx::Deltas::DeltaJob.new(delta_index_name(model)) | ||
| 13 | ) | ||
| 14 | |||
| 15 | Delayed::Job.enqueue( | ||
| 16 | ThinkingSphinx::Deltas::FlagAsDeletedJob.new( | ||
| 17 | core_index_name(model), instance.sphinx_document_id | ||
| 18 | ) | ||
| 19 | ) if instance | ||
| 20 | |||
| 21 | true | ||
| 22 | end | ||
| 23 | end | ||
| 24 | end | ||
| 25 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb new file mode 100644 index 0000000..f9511ec --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module Deltas | ||
| 3 | class DeltaJob | ||
| 4 | attr_accessor :index | ||
| 5 | |||
| 6 | def initialize(index) | ||
| 7 | @index = index | ||
| 8 | end | ||
| 9 | |||
| 10 | def perform | ||
| 11 | return true unless ThinkingSphinx.updates_enabled? && | ||
| 12 | ThinkingSphinx.deltas_enabled? | ||
| 13 | |||
| 14 | config = ThinkingSphinx::Configuration.instance | ||
| 15 | client = Riddle::Client.new config.address, config.port | ||
| 16 | |||
| 17 | output = `#{config.bin_path}indexer --config #{config.config_file} --rotate #{index}` | ||
| 18 | puts output unless ThinkingSphinx.suppress_delta_output? | ||
| 19 | |||
| 20 | true | ||
| 21 | end | ||
| 22 | end | ||
| 23 | end | ||
| 24 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb new file mode 100644 index 0000000..d6afd27 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module Deltas | ||
| 3 | class FlagAsDeletedJob | ||
| 4 | attr_accessor :index, :document_id | ||
| 5 | |||
| 6 | def initialize(index, document_id) | ||
| 7 | @index, @document_id = index, document_id | ||
| 8 | end | ||
| 9 | |||
| 10 | def perform | ||
| 11 | return true unless ThinkingSphinx.updates_enabled? | ||
| 12 | |||
| 13 | config = ThinkingSphinx::Configuration.instance | ||
| 14 | client = Riddle::Client.new config.address, config.port | ||
| 15 | |||
| 16 | client.update( | ||
| 17 | @index, | ||
| 18 | ['sphinx_deleted'], | ||
| 19 | {@document_id => [1]} | ||
| 20 | ) if ThinkingSphinx.sphinx_running? && | ||
| 21 | ThinkingSphinx::Search.search_for_id(@document_id, @index) | ||
| 22 | |||
| 23 | true | ||
| 24 | end | ||
| 25 | end | ||
| 26 | end | ||
| 27 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/job.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/job.rb new file mode 100644 index 0000000..de0a7cb --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/deltas/delayed_delta/job.rb | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module Deltas | ||
| 3 | class Job < Delayed::Job | ||
| 4 | def self.enqueue(object, priority = 0) | ||
| 5 | super unless duplicates_exist(object) | ||
| 6 | end | ||
| 7 | |||
| 8 | def self.cancel_thinking_sphinx_jobs | ||
| 9 | if connection.tables.include?("delayed_jobs") | ||
| 10 | delete_all("handler LIKE '--- !ruby/object:ThinkingSphinx::Deltas::%'") | ||
| 11 | end | ||
| 12 | end | ||
| 13 | |||
| 14 | private | ||
| 15 | |||
| 16 | def self.duplicates_exist(object) | ||
| 17 | count( | ||
| 18 | :conditions => { | ||
| 19 | :handler => object.to_yaml, | ||
| 20 | :locked_at => nil | ||
| 21 | } | ||
| 22 | ) > 0 | ||
| 23 | end | ||
| 24 | end | ||
| 25 | end | ||
| 26 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/facet.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/facet.rb new file mode 100644 index 0000000..e2db449 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/facet.rb | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | class Facet | ||
| 3 | attr_reader :reference | ||
| 4 | |||
| 5 | def initialize(reference) | ||
| 6 | @reference = reference | ||
| 7 | |||
| 8 | if reference.columns.length != 1 | ||
| 9 | raise "Can't translate Facets on multiple-column field or attribute" | ||
| 10 | end | ||
| 11 | end | ||
| 12 | |||
| 13 | def name | ||
| 14 | reference.unique_name | ||
| 15 | end | ||
| 16 | |||
| 17 | def attribute_name | ||
| 18 | # @attribute_name ||= case @reference | ||
| 19 | # when Attribute | ||
| 20 | # @reference.unique_name.to_s | ||
| 21 | # when Field | ||
| 22 | @attribute_name ||= @reference.unique_name.to_s + "_facet" | ||
| 23 | # end | ||
| 24 | end | ||
| 25 | |||
| 26 | def value(object, attribute_value) | ||
| 27 | return translate(object, attribute_value) if @reference.is_a?(Field) | ||
| 28 | |||
| 29 | case @reference.type | ||
| 30 | when :string | ||
| 31 | translate(object, attribute_value) | ||
| 32 | when :datetime | ||
| 33 | Time.at(attribute_value) | ||
| 34 | when :boolean | ||
| 35 | attribute_value > 0 | ||
| 36 | else | ||
| 37 | attribute_value | ||
| 38 | end | ||
| 39 | end | ||
| 40 | |||
| 41 | def to_s | ||
| 42 | name | ||
| 43 | end | ||
| 44 | |||
| 45 | private | ||
| 46 | |||
| 47 | def translate(object, attribute_value) | ||
| 48 | column.__stack.each { |method| | ||
| 49 | object = object.send(method) | ||
| 50 | } | ||
| 51 | object.send(column.__name) | ||
| 52 | end | ||
| 53 | |||
| 54 | def column | ||
| 55 | @reference.columns.first | ||
| 56 | end | ||
| 57 | end | ||
| 58 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/facet_collection.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/facet_collection.rb new file mode 100644 index 0000000..1ad9d1a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/facet_collection.rb | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | class FacetCollection < Hash | ||
| 3 | attr_accessor :arguments | ||
| 4 | |||
| 5 | def initialize(arguments) | ||
| 6 | @arguments = arguments.clone | ||
| 7 | @attribute_values = {} | ||
| 8 | @facets = [] | ||
| 9 | end | ||
| 10 | |||
| 11 | def add_from_results(facet, results) | ||
| 12 | facet = facet_from_object(results.first, facet) if facet.is_a?(String) | ||
| 13 | |||
| 14 | self[facet.name] ||= {} | ||
| 15 | @attribute_values[facet.name] ||= {} | ||
| 16 | @facets << facet | ||
| 17 | |||
| 18 | results.each_with_groupby_and_count { |result, group, count| | ||
| 19 | facet_value = facet.value(result, group) | ||
| 20 | |||
| 21 | self[facet.name][facet_value] ||= 0 | ||
| 22 | self[facet.name][facet_value] += count | ||
| 23 | @attribute_values[facet.name][facet_value] = group | ||
| 24 | } | ||
| 25 | end | ||
| 26 | |||
| 27 | def for(hash = {}) | ||
| 28 | arguments = @arguments.clone | ||
| 29 | options = arguments.extract_options! | ||
| 30 | options[:with] ||= {} | ||
| 31 | |||
| 32 | hash.each do |key, value| | ||
| 33 | attrib = facet_for_key(key).attribute_name | ||
| 34 | options[:with][attrib] = underlying_value key, value | ||
| 35 | end | ||
| 36 | |||
| 37 | arguments << options | ||
| 38 | ThinkingSphinx::Search.search *arguments | ||
| 39 | end | ||
| 40 | |||
| 41 | private | ||
| 42 | |||
| 43 | def underlying_value(key, value) | ||
| 44 | case value | ||
| 45 | when Array | ||
| 46 | value.collect { |item| underlying_value(key, item) } | ||
| 47 | else | ||
| 48 | @attribute_values[key][value] | ||
| 49 | end | ||
| 50 | end | ||
| 51 | |||
| 52 | def facet_for_key(key) | ||
| 53 | @facets.detect { |facet| facet.name == key } | ||
| 54 | end | ||
| 55 | |||
| 56 | def facet_from_object(object, name) | ||
| 57 | object.sphinx_facets.detect { |facet| facet.attribute_name == name } | ||
| 58 | end | ||
| 59 | end | ||
| 60 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/field.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/field.rb new file mode 100644 index 0000000..9edaede --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/field.rb | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | # Fields - holding the string data which Sphinx indexes for your searches. | ||
| 3 | # This class isn't really useful to you unless you're hacking around with the | ||
| 4 | # internals of Thinking Sphinx - but hey, don't let that stop you. | ||
| 5 | # | ||
| 6 | # One key thing to remember - if you're using the field manually to | ||
| 7 | # generate SQL statements, you'll need to set the base model, and all the | ||
| 8 | # associations. Which can get messy. Use Index.link!, it really helps. | ||
| 9 | # | ||
| 10 | class Field | ||
| 11 | attr_accessor :alias, :columns, :sortable, :associations, :model, :infixes, | ||
| 12 | :prefixes, :faceted | ||
| 13 | |||
| 14 | # To create a new field, you'll need to pass in either a single Column | ||
| 15 | # or an array of them, and some (optional) options. The columns are | ||
| 16 | # references to the data that will make up the field. | ||
| 17 | # | ||
| 18 | # Valid options are: | ||
| 19 | # - :as => :alias_name | ||
| 20 | # - :sortable => true | ||
| 21 | # - :infixes => true | ||
| 22 | # - :prefixes => true | ||
| 23 | # | ||
| 24 | # Alias is only required in three circumstances: when there's | ||
| 25 | # another attribute or field with the same name, when the column name is | ||
| 26 | # 'id', or when there's more than one column. | ||
| 27 | # | ||
| 28 | # Sortable defaults to false - but is quite useful when set to true, as | ||
| 29 | # it creates an attribute with the same string value (which Sphinx converts | ||
| 30 | # to an integer value), which can be sorted by. Thinking Sphinx is smart | ||
| 31 | # enough to realise that when you specify fields in sort statements, you | ||
| 32 | # mean their respective attributes. | ||
| 33 | # | ||
| 34 | # If you have partial matching enabled (ie: enable_star), then you can | ||
| 35 | # specify certain fields to have their prefixes and infixes indexed. Keep | ||
| 36 | # in mind, though, that Sphinx's default is _all_ fields - so once you | ||
| 37 | # highlight a particular field, no other fields in the index will have | ||
| 38 | # these partial indexes. | ||
| 39 | # | ||
| 40 | # Here's some examples: | ||
| 41 | # | ||
| 42 | # Field.new( | ||
| 43 | # Column.new(:name) | ||
| 44 | # ) | ||
| 45 | # | ||
| 46 | # Field.new( | ||
| 47 | # [Column.new(:first_name), Column.new(:last_name)], | ||
| 48 | # :as => :name, :sortable => true | ||
| 49 | # ) | ||
| 50 | # | ||
| 51 | # Field.new( | ||
| 52 | # [Column.new(:posts, :subject), Column.new(:posts, :content)], | ||
| 53 | # :as => :posts, :prefixes => true | ||
| 54 | # ) | ||
| 55 | # | ||
| 56 | def initialize(columns, options = {}) | ||
| 57 | @columns = Array(columns) | ||
| 58 | @associations = {} | ||
| 59 | |||
| 60 | raise "Cannot define a field with no columns. Maybe you are trying to index a field with a reserved name (id, name). You can fix this error by using a symbol rather than a bare name (:id instead of id)." if @columns.empty? || @columns.any? { |column| !column.respond_to?(:__stack) } | ||
| 61 | |||
| 62 | @alias = options[:as] | ||
| 63 | @sortable = options[:sortable] || false | ||
| 64 | @infixes = options[:infixes] || false | ||
| 65 | @prefixes = options[:prefixes] || false | ||
| 66 | @faceted = options[:facet] || false | ||
| 67 | end | ||
| 68 | |||
| 69 | # Get the part of the SELECT clause related to this field. Don't forget | ||
| 70 | # to set your model and associations first though. | ||
| 71 | # | ||
| 72 | # This will concatenate strings if there's more than one data source or | ||
| 73 | # multiple data values (has_many or has_and_belongs_to_many associations). | ||
| 74 | # | ||
| 75 | def to_select_sql | ||
| 76 | clause = @columns.collect { |column| | ||
| 77 | column_with_prefix(column) | ||
| 78 | }.join(', ') | ||
| 79 | |||
| 80 | clause = adapter.concatenate(clause) if concat_ws? | ||
| 81 | clause = adapter.group_concatenate(clause) if is_many? | ||
| 82 | |||
| 83 | "#{adapter.cast_to_string clause } AS #{quote_column(unique_name)}" | ||
| 84 | end | ||
| 85 | |||
| 86 | # Get the part of the GROUP BY clause related to this field - if one is | ||
| 87 | # needed. If not, all you'll get back is nil. The latter will happen if | ||
| 88 | # there's multiple data values (read: a has_many or has_and_belongs_to_many | ||
| 89 | # association). | ||
| 90 | # | ||
| 91 | def to_group_sql | ||
| 92 | case | ||
| 93 | when is_many?, ThinkingSphinx.use_group_by_shortcut? | ||
| 94 | nil | ||
| 95 | else | ||
| 96 | @columns.collect { |column| | ||
| 97 | column_with_prefix(column) | ||
| 98 | } | ||
| 99 | end | ||
| 100 | end | ||
| 101 | |||
| 102 | # Returns the unique name of the field - which is either the alias of | ||
| 103 | # the field, or the name of the only column - if there is only one. If | ||
| 104 | # there isn't, there should be an alias. Else things probably won't work. | ||
| 105 | # Consider yourself warned. | ||
| 106 | # | ||
| 107 | def unique_name | ||
| 108 | if @columns.length == 1 | ||
| 109 | @alias || @columns.first.__name | ||
| 110 | else | ||
| 111 | @alias | ||
| 112 | end | ||
| 113 | end | ||
| 114 | |||
| 115 | def to_facet | ||
| 116 | return nil unless @faceted | ||
| 117 | |||
| 118 | ThinkingSphinx::Facet.new(self) | ||
| 119 | end | ||
| 120 | |||
| 121 | private | ||
| 122 | |||
| 123 | def adapter | ||
| 124 | @adapter ||= @model.sphinx_database_adapter | ||
| 125 | end | ||
| 126 | |||
| 127 | def quote_column(column) | ||
| 128 | @model.connection.quote_column_name(column) | ||
| 129 | end | ||
| 130 | |||
| 131 | # Indication of whether the columns should be concatenated with a space | ||
| 132 | # between each value. True if there's either multiple sources or multiple | ||
| 133 | # associations. | ||
| 134 | # | ||
| 135 | def concat_ws? | ||
| 136 | @columns.length > 1 || multiple_associations? | ||
| 137 | end | ||
| 138 | |||
| 139 | # Checks whether any column requires multiple associations (which only | ||
| 140 | # happens for polymorphic situations). | ||
| 141 | # | ||
| 142 | def multiple_associations? | ||
| 143 | associations.any? { |col,assocs| assocs.length > 1 } | ||
| 144 | end | ||
| 145 | |||
| 146 | # Builds a column reference tied to the appropriate associations. This | ||
| 147 | # dives into the associations hash and their corresponding joins to | ||
| 148 | # figure out how to correctly reference a column in SQL. | ||
| 149 | # | ||
| 150 | def column_with_prefix(column) | ||
| 151 | if column.is_string? | ||
| 152 | column.__name | ||
| 153 | elsif associations[column].empty? | ||
| 154 | "#{@model.quoted_table_name}.#{quote_column(column.__name)}" | ||
| 155 | else | ||
| 156 | associations[column].collect { |assoc| | ||
| 157 | assoc.has_column?(column.__name) ? | ||
| 158 | "#{@model.connection.quote_table_name(assoc.join.aliased_table_name)}" + | ||
| 159 | ".#{quote_column(column.__name)}" : | ||
| 160 | nil | ||
| 161 | }.compact.join(', ') | ||
| 162 | end | ||
| 163 | end | ||
| 164 | |||
| 165 | # Could there be more than one value related to the parent record? If so, | ||
| 166 | # then this will return true. If not, false. It's that simple. | ||
| 167 | # | ||
| 168 | def is_many? | ||
| 169 | associations.values.flatten.any? { |assoc| assoc.is_many? } | ||
| 170 | end | ||
| 171 | end | ||
| 172 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index.rb new file mode 100644 index 0000000..30cfe38 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index.rb | |||
| @@ -0,0 +1,423 @@ | |||
| 1 | require 'thinking_sphinx/index/builder' | ||
| 2 | require 'thinking_sphinx/index/faux_column' | ||
| 3 | |||
| 4 | module ThinkingSphinx | ||
| 5 | # The Index class is a ruby representation of a Sphinx source (not a Sphinx | ||
| 6 | # index - yes, I know it's a little confusing. You'll manage). This is | ||
| 7 | # another 'internal' Thinking Sphinx class - if you're using it directly, | ||
| 8 | # you either know what you're doing, or messing with things beyond your ken. | ||
| 9 | # Enjoy. | ||
| 10 | # | ||
| 11 | class Index | ||
| 12 | attr_accessor :model, :fields, :attributes, :conditions, :groupings, | ||
| 13 | :delta_object, :options | ||
| 14 | |||
| 15 | # Create a new index instance by passing in the model it is tied to, and | ||
| 16 | # a block to build it with (optional but recommended). For documentation | ||
| 17 | # on the syntax for inside the block, the Builder class is what you want. | ||
| 18 | # | ||
| 19 | # Quick Example: | ||
| 20 | # | ||
| 21 | # Index.new(User) do | ||
| 22 | # indexes login, email | ||
| 23 | # | ||
| 24 | # has created_at | ||
| 25 | # | ||
| 26 | # set_property :delta => true | ||
| 27 | # end | ||
| 28 | # | ||
| 29 | def initialize(model, &block) | ||
| 30 | @model = model | ||
| 31 | @associations = {} | ||
| 32 | @fields = [] | ||
| 33 | @attributes = [] | ||
| 34 | @conditions = [] | ||
| 35 | @groupings = [] | ||
| 36 | @options = {} | ||
| 37 | @delta_object = nil | ||
| 38 | |||
| 39 | initialize_from_builder(&block) if block_given? | ||
| 40 | end | ||
| 41 | |||
| 42 | def name | ||
| 43 | self.class.name(@model) | ||
| 44 | end | ||
| 45 | |||
| 46 | def self.name(model) | ||
| 47 | model.name.underscore.tr(':/\\', '_') | ||
| 48 | end | ||
| 49 | |||
| 50 | def to_riddle_for_core(offset, index) | ||
| 51 | add_internal_attributes_and_facets | ||
| 52 | link! | ||
| 53 | |||
| 54 | source = Riddle::Configuration::SQLSource.new( | ||
| 55 | "#{name}_core_#{index}", adapter.sphinx_identifier | ||
| 56 | ) | ||
| 57 | |||
| 58 | set_source_database_settings source | ||
| 59 | set_source_attributes source, offset | ||
| 60 | set_source_sql source, offset | ||
| 61 | set_source_settings source | ||
| 62 | |||
| 63 | source | ||
| 64 | end | ||
| 65 | |||
| 66 | def to_riddle_for_delta(offset, index) | ||
| 67 | add_internal_attributes_and_facets | ||
| 68 | link! | ||
| 69 | |||
| 70 | source = Riddle::Configuration::SQLSource.new( | ||
| 71 | "#{name}_delta_#{index}", adapter.sphinx_identifier | ||
| 72 | ) | ||
| 73 | source.parent = "#{name}_core_#{index}" | ||
| 74 | |||
| 75 | set_source_database_settings source | ||
| 76 | set_source_attributes source, offset | ||
| 77 | set_source_sql source, offset, true | ||
| 78 | |||
| 79 | source | ||
| 80 | end | ||
| 81 | |||
| 82 | # Link all the fields and associations to their corresponding | ||
| 83 | # associations and joins. This _must_ be called before interrogating | ||
| 84 | # the index's fields and associations for anything that may reference | ||
| 85 | # their SQL structure. | ||
| 86 | # | ||
| 87 | def link! | ||
| 88 | base = ::ActiveRecord::Associations::ClassMethods::JoinDependency.new( | ||
| 89 | @model, [], nil | ||
| 90 | ) | ||
| 91 | |||
| 92 | @fields.each { |field| | ||
| 93 | field.model ||= @model | ||
| 94 | field.columns.each { |col| | ||
| 95 | field.associations[col] = associations(col.__stack.clone) | ||
| 96 | field.associations[col].each { |assoc| assoc.join_to(base) } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | @attributes.each { |attribute| | ||
| 101 | attribute.model ||= @model | ||
| 102 | attribute.columns.each { |col| | ||
| 103 | attribute.associations[col] = associations(col.__stack.clone) | ||
| 104 | attribute.associations[col].each { |assoc| assoc.join_to(base) } | ||
| 105 | } | ||
| 106 | } | ||
| 107 | end | ||
| 108 | |||
| 109 | # Flag to indicate whether this index has a corresponding delta index. | ||
| 110 | # | ||
| 111 | def delta? | ||
| 112 | !@delta_object.nil? | ||
| 113 | end | ||
| 114 | |||
| 115 | def adapter | ||
| 116 | @adapter ||= @model.sphinx_database_adapter | ||
| 117 | end | ||
| 118 | |||
| 119 | def prefix_fields | ||
| 120 | @fields.select { |field| field.prefixes } | ||
| 121 | end | ||
| 122 | |||
| 123 | def infix_fields | ||
| 124 | @fields.select { |field| field.infixes } | ||
| 125 | end | ||
| 126 | |||
| 127 | def index_options | ||
| 128 | all_index_options = ThinkingSphinx::Configuration.instance.index_options.clone | ||
| 129 | @options.keys.select { |key| | ||
| 130 | ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s) | ||
| 131 | }.each { |key| all_index_options[key.to_sym] = @options[key] } | ||
| 132 | all_index_options | ||
| 133 | end | ||
| 134 | |||
| 135 | def quote_column(column) | ||
| 136 | @model.connection.quote_column_name(column) | ||
| 137 | end | ||
| 138 | |||
| 139 | private | ||
| 140 | |||
| 141 | def utf8? | ||
| 142 | self.index_options[:charset_type] == "utf-8" | ||
| 143 | end | ||
| 144 | |||
| 145 | # Does all the magic with the block provided to the base #initialize. | ||
| 146 | # Creates a new class subclassed from Builder, and evaluates the block | ||
| 147 | # on it, then pulls all relevant settings - fields, attributes, conditions, | ||
| 148 | # properties - into the new index. | ||
| 149 | # | ||
| 150 | # Also creates a CRC attribute for the model. | ||
| 151 | # | ||
| 152 | def initialize_from_builder(&block) | ||
| 153 | builder = Class.new(Builder) | ||
| 154 | builder.setup | ||
| 155 | |||
| 156 | builder.instance_eval &block | ||
| 157 | |||
| 158 | unless @model.descends_from_active_record? | ||
| 159 | stored_class = @model.store_full_sti_class ? @model.name : @model.name.demodulize | ||
| 160 | builder.where("#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)} = '#{stored_class}'") | ||
| 161 | end | ||
| 162 | |||
| 163 | set_model = Proc.new { |item| item.model = @model } | ||
| 164 | |||
| 165 | @fields = builder.fields &set_model | ||
| 166 | @attributes = builder.attributes.each &set_model | ||
| 167 | @conditions = builder.conditions | ||
| 168 | @groupings = builder.groupings | ||
| 169 | @delta_object = ThinkingSphinx::Deltas.parse self, builder.properties | ||
| 170 | @options = builder.properties | ||
| 171 | |||
| 172 | is_faceted = Proc.new { |item| item.faceted } | ||
| 173 | add_facet = Proc.new { |item| @model.sphinx_facets << item.to_facet } | ||
| 174 | |||
| 175 | @model.sphinx_facets ||= [] | ||
| 176 | @fields.select( &is_faceted).each &add_facet | ||
| 177 | @attributes.select(&is_faceted).each &add_facet | ||
| 178 | |||
| 179 | # We want to make sure that if the database doesn't exist, then Thinking | ||
| 180 | # Sphinx doesn't mind when running non-TS tasks (like db:create, db:drop | ||
| 181 | # and db:migrate). It's a bit hacky, but I can't think of a better way. | ||
| 182 | rescue StandardError => err | ||
| 183 | case err.class.name | ||
| 184 | when "Mysql::Error", "Java::JavaSql::SQLException", "ActiveRecord::StatementInvalid" | ||
| 185 | return | ||
| 186 | else | ||
| 187 | raise err | ||
| 188 | end | ||
| 189 | end | ||
| 190 | |||
| 191 | # Returns all associations used amongst all the fields and attributes. | ||
| 192 | # This includes all associations between the model and what the actual | ||
| 193 | # columns are from. | ||
| 194 | # | ||
| 195 | def all_associations | ||
| 196 | @all_associations ||= ( | ||
| 197 | # field associations | ||
| 198 | @fields.collect { |field| | ||
| 199 | field.associations.values | ||
| 200 | }.flatten + | ||
| 201 | # attribute associations | ||
| 202 | @attributes.collect { |attrib| | ||
| 203 | attrib.associations.values if attrib.include_as_association? | ||
| 204 | }.compact.flatten | ||
| 205 | ).uniq.collect { |assoc| | ||
| 206 | # get ancestors as well as column-level associations | ||
| 207 | assoc.ancestors | ||
| 208 | }.flatten.uniq | ||
| 209 | end | ||
| 210 | |||
| 211 | # Gets a stack of associations for a specific path. | ||
| 212 | # | ||
| 213 | def associations(path, parent = nil) | ||
| 214 | assocs = [] | ||
| 215 | |||
| 216 | if parent.nil? | ||
| 217 | assocs = association(path.shift) | ||
| 218 | else | ||
| 219 | assocs = parent.children(path.shift) | ||
| 220 | end | ||
| 221 | |||
| 222 | until path.empty? | ||
| 223 | point = path.shift | ||
| 224 | assocs = assocs.collect { |assoc| | ||
| 225 | assoc.children(point) | ||
| 226 | }.flatten | ||
| 227 | end | ||
| 228 | |||
| 229 | assocs | ||
| 230 | end | ||
| 231 | |||
| 232 | # Gets the association stack for a specific key. | ||
| 233 | # | ||
| 234 | def association(key) | ||
| 235 | @associations[key] ||= Association.children(@model, key) | ||
| 236 | end | ||
| 237 | |||
| 238 | def crc_column | ||
| 239 | if @model.column_names.include?(@model.inheritance_column) | ||
| 240 | adapter.cast_to_unsigned(adapter.convert_nulls( | ||
| 241 | adapter.crc(adapter.quote_with_table(@model.inheritance_column), true), | ||
| 242 | @model.to_crc32 | ||
| 243 | )) | ||
| 244 | else | ||
| 245 | @model.to_crc32.to_s | ||
| 246 | end | ||
| 247 | end | ||
| 248 | |||
| 249 | def add_internal_attributes_and_facets | ||
| 250 | add_internal_attribute :sphinx_internal_id, :integer, @model.primary_key.to_sym | ||
| 251 | add_internal_attribute :class_crc, :integer, crc_column, true | ||
| 252 | add_internal_attribute :subclass_crcs, :multi, subclasses_to_s | ||
| 253 | add_internal_attribute :sphinx_deleted, :integer, "0" | ||
| 254 | |||
| 255 | add_internal_facet :class_crc | ||
| 256 | end | ||
| 257 | |||
| 258 | def add_internal_attribute(name, type, contents, facet = false) | ||
| 259 | return unless attribute_by_alias(name).nil? | ||
| 260 | |||
| 261 | @attributes << Attribute.new( | ||
| 262 | FauxColumn.new(contents), | ||
| 263 | :type => type, | ||
| 264 | :as => name, | ||
| 265 | :facet => facet | ||
| 266 | ) | ||
| 267 | end | ||
| 268 | |||
| 269 | def add_internal_facet(name) | ||
| 270 | return unless facet_by_alias(name).nil? | ||
| 271 | |||
| 272 | @model.sphinx_facets << ClassFacet.new(attribute_by_alias(name)) | ||
| 273 | end | ||
| 274 | |||
| 275 | def attribute_by_alias(attr_alias) | ||
| 276 | @attributes.detect { |attrib| attrib.alias == attr_alias } | ||
| 277 | end | ||
| 278 | |||
| 279 | def facet_by_alias(name) | ||
| 280 | @model.sphinx_facets.detect { |facet| facet.name == name } | ||
| 281 | end | ||
| 282 | |||
| 283 | def subclasses_to_s | ||
| 284 | "'" + (@model.send(:subclasses).collect { |klass| | ||
| 285 | klass.to_crc32.to_s | ||
| 286 | } << @model.to_crc32.to_s).join(",") + "'" | ||
| 287 | end | ||
| 288 | |||
| 289 | def set_source_database_settings(source) | ||
| 290 | config = @model.connection.instance_variable_get(:@config) | ||
| 291 | |||
| 292 | source.sql_host = config[:host] || "localhost" | ||
| 293 | source.sql_user = config[:username] || config[:user] || "" | ||
| 294 | source.sql_pass = (config[:password].to_s || "").gsub('#', '\#') | ||
| 295 | source.sql_db = config[:database] | ||
| 296 | source.sql_port = config[:port] | ||
| 297 | source.sql_sock = config[:socket] | ||
| 298 | end | ||
| 299 | |||
| 300 | def set_source_attributes(source, offset = nil) | ||
| 301 | attributes.each do |attrib| | ||
| 302 | source.send(attrib.type_to_config) << attrib.config_value(offset) | ||
| 303 | end | ||
| 304 | end | ||
| 305 | |||
| 306 | def set_source_sql(source, offset, delta = false) | ||
| 307 | source.sql_query = to_sql(:offset => offset, :delta => delta).gsub(/\n/, ' ') | ||
| 308 | source.sql_query_range = to_sql_query_range(:delta => delta) | ||
| 309 | source.sql_query_info = to_sql_query_info(offset) | ||
| 310 | |||
| 311 | source.sql_query_pre += send(!delta ? :sql_query_pre_for_core : :sql_query_pre_for_delta) | ||
| 312 | |||
| 313 | if @options[:group_concat_max_len] | ||
| 314 | source.sql_query_pre << "SET SESSION group_concat_max_len = #{@options[:group_concat_max_len]}" | ||
| 315 | end | ||
| 316 | |||
| 317 | source.sql_query_pre += [adapter.utf8_query_pre].compact if utf8? | ||
| 318 | end | ||
| 319 | |||
| 320 | def set_source_settings(source) | ||
| 321 | ThinkingSphinx::Configuration.instance.source_options.each do |key, value| | ||
| 322 | source.send("#{key}=".to_sym, value) | ||
| 323 | end | ||
| 324 | |||
| 325 | @options.each do |key, value| | ||
| 326 | source.send("#{key}=".to_sym, value) if ThinkingSphinx::Configuration::SourceOptions.include?(key.to_s) && !value.nil? | ||
| 327 | end | ||
| 328 | end | ||
| 329 | |||
| 330 | def sql_query_pre_for_core | ||
| 331 | if self.delta? && !@delta_object.reset_query(@model).blank? | ||
| 332 | [@delta_object.reset_query(@model)] | ||
| 333 | else | ||
| 334 | [] | ||
| 335 | end | ||
| 336 | end | ||
| 337 | |||
| 338 | def sql_query_pre_for_delta | ||
| 339 | [""] | ||
| 340 | end | ||
| 341 | |||
| 342 | # Generates the big SQL statement to get the data back for all the fields | ||
| 343 | # and attributes, using all the relevant association joins. If you want | ||
| 344 | # the version filtered for delta values, send through :delta => true in the | ||
| 345 | # options. Won't do much though if the index isn't set up to support a | ||
| 346 | # delta sibling. | ||
| 347 | # | ||
| 348 | # Examples: | ||
| 349 | # | ||
| 350 | # index.to_sql | ||
| 351 | # index.to_sql(:delta => true) | ||
| 352 | # | ||
| 353 | def to_sql(options={}) | ||
| 354 | assocs = all_associations | ||
| 355 | |||
| 356 | where_clause = "" | ||
| 357 | if self.delta? && !@delta_object.clause(@model, options[:delta]).blank? | ||
| 358 | where_clause << " AND #{@delta_object.clause(@model, options[:delta])}" | ||
| 359 | end | ||
| 360 | unless @conditions.empty? | ||
| 361 | where_clause << " AND " << @conditions.join(" AND ") | ||
| 362 | end | ||
| 363 | |||
| 364 | internal_groupings = [] | ||
| 365 | if @model.column_names.include?(@model.inheritance_column) | ||
| 366 | internal_groupings << "#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)}" | ||
| 367 | end | ||
| 368 | |||
| 369 | unique_id_expr = ThinkingSphinx.unique_id_expression(options[:offset]) | ||
| 370 | |||
| 371 | sql = <<-SQL | ||
| 372 | SELECT #{ ( | ||
| 373 | ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key)} #{unique_id_expr} AS #{quote_column(@model.primary_key)} "] + | ||
| 374 | @fields.collect { |field| field.to_select_sql } + | ||
| 375 | @attributes.collect { |attribute| attribute.to_select_sql } | ||
| 376 | ).compact.join(", ") } | ||
| 377 | FROM #{ @model.table_name } | ||
| 378 | #{ assocs.collect { |assoc| assoc.to_sql }.join(' ') } | ||
| 379 | WHERE #{@model.quoted_table_name}.#{quote_column(@model.primary_key)} >= $start | ||
| 380 | AND #{@model.quoted_table_name}.#{quote_column(@model.primary_key)} <= $end | ||
| 381 | #{ where_clause } | ||
| 382 | GROUP BY #{ ( | ||
| 383 | ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key)}"] + | ||
| 384 | @fields.collect { |field| field.to_group_sql }.compact + | ||
| 385 | @attributes.collect { |attribute| attribute.to_group_sql }.compact + | ||
| 386 | @groupings + internal_groupings | ||
| 387 | ).join(", ") } | ||
| 388 | SQL | ||
| 389 | |||
| 390 | sql += " ORDER BY NULL" if adapter.sphinx_identifier == "mysql" | ||
| 391 | sql | ||
| 392 | end | ||
| 393 | |||
| 394 | # Simple helper method for the query info SQL - which is a statement that | ||
| 395 | # returns the single row for a corresponding id. | ||
| 396 | # | ||
| 397 | def to_sql_query_info(offset) | ||
| 398 | "SELECT * FROM #{@model.quoted_table_name} WHERE " + | ||
| 399 | " #{quote_column(@model.primary_key)} = (($id - #{offset}) / #{ThinkingSphinx.indexed_models.size})" | ||
| 400 | end | ||
| 401 | |||
| 402 | # Simple helper method for the query range SQL - which is a statement that | ||
| 403 | # returns minimum and maximum id values. These can be filtered by delta - | ||
| 404 | # so pass in :delta => true to get the delta version of the SQL. | ||
| 405 | # | ||
| 406 | def to_sql_query_range(options={}) | ||
| 407 | min_statement = adapter.convert_nulls( | ||
| 408 | "MIN(#{quote_column(@model.primary_key)})", 1 | ||
| 409 | ) | ||
| 410 | max_statement = adapter.convert_nulls( | ||
| 411 | "MAX(#{quote_column(@model.primary_key)})", 1 | ||
| 412 | ) | ||
| 413 | |||
| 414 | sql = "SELECT #{min_statement}, #{max_statement} " + | ||
| 415 | "FROM #{@model.quoted_table_name} " | ||
| 416 | if self.delta? && !@delta_object.clause(@model, options[:delta]).blank? | ||
| 417 | sql << "WHERE #{@delta_object.clause(@model, options[:delta])}" | ||
| 418 | end | ||
| 419 | |||
| 420 | sql | ||
| 421 | end | ||
| 422 | end | ||
| 423 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb new file mode 100644 index 0000000..dbd2ba0 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb | |||
| @@ -0,0 +1,264 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | class Index | ||
| 3 | # The Builder class is the core for the index definition block processing. | ||
| 4 | # There are four methods you really need to pay attention to: | ||
| 5 | # - indexes (aliased to includes and attribute) | ||
| 6 | # - has (aliased to attribute) | ||
| 7 | # - where | ||
| 8 | # - set_property (aliased to set_properties) | ||
| 9 | # | ||
| 10 | # The first two of these methods allow you to define what data makes up | ||
| 11 | # your indexes. #where provides a method to add manual SQL conditions, and | ||
| 12 | # set_property allows you to set some settings on a per-index basis. Check | ||
| 13 | # out each method's documentation for better ideas of usage. | ||
| 14 | # | ||
| 15 | class Builder | ||
| 16 | class << self | ||
| 17 | # No idea where this is coming from - haven't found it in any ruby or | ||
| 18 | # rails documentation. It's not needed though, so it gets undef'd. | ||
| 19 | # Hopefully the list of methods that get in the way doesn't get too | ||
| 20 | # long. | ||
| 21 | HiddenMethods = [:parent, :name, :id, :type].each { |method| | ||
| 22 | define_method(method) { | ||
| 23 | caller.grep(/irb.completion/).empty? ? method_missing(method) : super | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | attr_accessor :fields, :attributes, :properties, :conditions, | ||
| 28 | :groupings | ||
| 29 | |||
| 30 | # Set up all the collections. Consider this the equivalent of an | ||
| 31 | # instance's initialize method. | ||
| 32 | # | ||
| 33 | def setup | ||
| 34 | @fields = [] | ||
| 35 | @attributes = [] | ||
| 36 | @properties = {} | ||
| 37 | @conditions = [] | ||
| 38 | @groupings = [] | ||
| 39 | end | ||
| 40 | |||
| 41 | # This is how you add fields - the strings Sphinx looks at - to your | ||
| 42 | # index. Technically, to use this method, you need to pass in some | ||
| 43 | # columns and options - but there's some neat method_missing stuff | ||
| 44 | # happening, so lets stick to the expected syntax within a define_index | ||
| 45 | # block. | ||
| 46 | # | ||
| 47 | # Expected options are :as, which points to a column alias in symbol | ||
| 48 | # form, and :sortable, which indicates whether you want to sort by this | ||
| 49 | # field. | ||
| 50 | # | ||
| 51 | # Adding Single-Column Fields: | ||
| 52 | # | ||
| 53 | # You can use symbols or methods - and can chain methods together to | ||
| 54 | # get access down the associations tree. | ||
| 55 | # | ||
| 56 | # indexes :id, :as => :my_id | ||
| 57 | # indexes :name, :sortable => true | ||
| 58 | # indexes first_name, last_name, :sortable => true | ||
| 59 | # indexes users.posts.content, :as => :post_content | ||
| 60 | # indexes users(:id), :as => :user_ids | ||
| 61 | # | ||
| 62 | # Keep in mind that if any keywords for Ruby methods - such as id or | ||
| 63 | # name - clash with your column names, you need to use the symbol | ||
| 64 | # version (see the first, second and last examples above). | ||
| 65 | # | ||
| 66 | # If you specify multiple columns (example #2), a field will be created | ||
| 67 | # for each. Don't use the :as option in this case. If you want to merge | ||
| 68 | # those columns together, continue reading. | ||
| 69 | # | ||
| 70 | # Adding Multi-Column Fields: | ||
| 71 | # | ||
| 72 | # indexes [first_name, last_name], :as => :name | ||
| 73 | # indexes [location, parent.location], :as => :location | ||
| 74 | # | ||
| 75 | # To combine multiple columns into a single field, you need to wrap | ||
| 76 | # them in an Array, as shown by the above examples. There's no | ||
| 77 | # limitations on whether they're symbols or methods or what level of | ||
| 78 | # associations they come from. | ||
| 79 | # | ||
| 80 | # Adding SQL Fragment Fields | ||
| 81 | # | ||
| 82 | # You can also define a field using an SQL fragment, useful for when | ||
| 83 | # you would like to index a calculated value. | ||
| 84 | # | ||
| 85 | # indexes "age < 18", :as => :minor | ||
| 86 | # | ||
| 87 | def indexes(*args) | ||
| 88 | options = args.extract_options! | ||
| 89 | args.each do |columns| | ||
| 90 | field = Field.new(FauxColumn.coerce(columns), options) | ||
| 91 | fields << field | ||
| 92 | |||
| 93 | add_sort_attribute field, options if field.sortable | ||
| 94 | add_facet_attribute field, options if field.faceted | ||
| 95 | end | ||
| 96 | end | ||
| 97 | alias_method :field, :indexes | ||
| 98 | alias_method :includes, :indexes | ||
| 99 | |||
| 100 | # This is the method to add attributes to your index (hence why it is | ||
| 101 | # aliased as 'attribute'). The syntax is the same as #indexes, so use | ||
| 102 | # that as starting point, but keep in mind the following points. | ||
| 103 | # | ||
| 104 | # An attribute can have an alias (the :as option), but it is always | ||
| 105 | # sortable - so you don't need to explicitly request that. You _can_ | ||
| 106 | # specify the data type of the attribute (the :type option), but the | ||
| 107 | # code's pretty good at figuring that out itself from peering into the | ||
| 108 | # database. | ||
| 109 | # | ||
| 110 | # Attributes are limited to the following types: integers, floats, | ||
| 111 | # datetimes (converted to timestamps), booleans and strings. Don't | ||
| 112 | # forget that Sphinx converts string attributes to integers, which are | ||
| 113 | # useful for sorting, but that's about it. | ||
| 114 | # | ||
| 115 | # You can also have a collection of integers for multi-value attributes | ||
| 116 | # (MVAs). Generally these would be through a has_many relationship, | ||
| 117 | # like in this example: | ||
| 118 | # | ||
| 119 | # has posts(:id), :as => :post_ids | ||
| 120 | # | ||
| 121 | # This allows you to filter on any of the values tied to a specific | ||
| 122 | # record. Might be best to read through the Sphinx documentation to get | ||
| 123 | # a better idea of that though. | ||
| 124 | # | ||
| 125 | # Adding SQL Fragment Attributes | ||
| 126 | # | ||
| 127 | # You can also define an attribute using an SQL fragment, useful for | ||
| 128 | # when you would like to index a calculated value. Don't forget to set | ||
| 129 | # the type of the attribute though: | ||
| 130 | # | ||
| 131 | # has "age < 18", :as => :minor, :type => :boolean | ||
| 132 | # | ||
| 133 | # If you're creating attributes for latitude and longitude, don't | ||
| 134 | # forget that Sphinx expects these values to be in radians. | ||
| 135 | # | ||
| 136 | def has(*args) | ||
| 137 | options = args.extract_options! | ||
| 138 | args.each do |columns| | ||
| 139 | attribute = Attribute.new(FauxColumn.coerce(columns), options) | ||
| 140 | attributes << attribute | ||
| 141 | |||
| 142 | add_facet_attribute attribute, options if attribute.faceted | ||
| 143 | end | ||
| 144 | end | ||
| 145 | alias_method :attribute, :has | ||
| 146 | |||
| 147 | def facet(*args) | ||
| 148 | options = args.extract_options! | ||
| 149 | options[:facet] = true | ||
| 150 | |||
| 151 | args.each do |columns| | ||
| 152 | attribute = Attribute.new(FauxColumn.coerce(columns), options) | ||
| 153 | attributes << attribute | ||
| 154 | |||
| 155 | add_facet_attribute attribute, options | ||
| 156 | end | ||
| 157 | end | ||
| 158 | |||
| 159 | # Use this method to add some manual SQL conditions for your index | ||
| 160 | # request. You can pass in as many strings as you like, they'll get | ||
| 161 | # joined together with ANDs later on. | ||
| 162 | # | ||
| 163 | # where "user_id = 10" | ||
| 164 | # where "parent_type = 'Article'", "created_at < NOW()" | ||
| 165 | # | ||
| 166 | def where(*args) | ||
| 167 | @conditions += args | ||
| 168 | end | ||
| 169 | |||
| 170 | # Use this method to add some manual SQL strings to the GROUP BY | ||
| 171 | # clause. You can pass in as many strings as you'd like, they'll get | ||
| 172 | # joined together with commas later on. | ||
| 173 | # | ||
| 174 | # group_by "lat", "lng" | ||
| 175 | # | ||
| 176 | def group_by(*args) | ||
| 177 | @groupings += args | ||
| 178 | end | ||
| 179 | |||
| 180 | # This is what to use to set properties on the index. Chief amongst | ||
| 181 | # those is the delta property - to allow automatic updates to your | ||
| 182 | # indexes as new models are added and edited - but also you can | ||
| 183 | # define search-related properties which will be the defaults for all | ||
| 184 | # searches on the model. | ||
| 185 | # | ||
| 186 | # set_property :delta => true | ||
| 187 | # set_property :field_weights => {"name" => 100} | ||
| 188 | # set_property :order => "name ASC" | ||
| 189 | # set_property :include => :picture | ||
| 190 | # set_property :select => 'name' | ||
| 191 | # | ||
| 192 | # Also, the following two properties are particularly relevant for | ||
| 193 | # geo-location searching - latitude_attr and longitude_attr. If your | ||
| 194 | # attributes for these two values are named something other than | ||
| 195 | # lat/latitude or lon/long/longitude, you can dictate what they are | ||
| 196 | # when defining the index, so you don't need to specify them for every | ||
| 197 | # geo-related search. | ||
| 198 | # | ||
| 199 | # set_property :latitude_attr => "lt", :longitude_attr => "lg" | ||
| 200 | # | ||
| 201 | # Please don't forget to add a boolean field named 'delta' to your | ||
| 202 | # model's database table if enabling the delta index for it. | ||
| 203 | # Valid options for the delta property are: | ||
| 204 | # | ||
| 205 | # true | ||
| 206 | # false | ||
| 207 | # :default | ||
| 208 | # :delayed | ||
| 209 | # :datetime | ||
| 210 | # | ||
| 211 | # You can also extend ThinkingSphinx::Deltas::DefaultDelta to implement | ||
| 212 | # your own handling for delta indexing. | ||
| 213 | |||
| 214 | def set_property(*args) | ||
| 215 | options = args.extract_options! | ||
| 216 | if options.empty? | ||
| 217 | @properties[args[0]] = args[1] | ||
| 218 | else | ||
| 219 | @properties.merge!(options) | ||
| 220 | end | ||
| 221 | end | ||
| 222 | alias_method :set_properties, :set_property | ||
| 223 | |||
| 224 | # Handles the generation of new columns for the field and attribute | ||
| 225 | # definitions. | ||
| 226 | # | ||
| 227 | def method_missing(method, *args) | ||
| 228 | FauxColumn.new(method, *args) | ||
| 229 | end | ||
| 230 | |||
| 231 | # A method to allow adding fields from associations which have names | ||
| 232 | # that clash with method names in the Builder class (ie: properties, | ||
| 233 | # fields, attributes). | ||
| 234 | # | ||
| 235 | # Example: indexes assoc(:properties).column | ||
| 236 | # | ||
| 237 | def assoc(assoc, *args) | ||
| 238 | FauxColumn.new(assoc, *args) | ||
| 239 | end | ||
| 240 | |||
| 241 | private | ||
| 242 | |||
| 243 | def add_sort_attribute(field, options) | ||
| 244 | add_internal_attribute field, options, "_sort" | ||
| 245 | end | ||
| 246 | |||
| 247 | def add_facet_attribute(resource, options) | ||
| 248 | add_internal_attribute resource, options, "_facet", true | ||
| 249 | end | ||
| 250 | |||
| 251 | def add_internal_attribute(resource, options, suffix, crc = false) | ||
| 252 | @attributes << Attribute.new( | ||
| 253 | resource.columns.collect { |col| col.clone }, | ||
| 254 | options.merge( | ||
| 255 | :type => resource.is_a?(Field) ? :string : nil, | ||
| 256 | :as => resource.unique_name.to_s.concat(suffix).to_sym, | ||
| 257 | :crc => crc | ||
| 258 | ).except(:facet) | ||
| 259 | ) | ||
| 260 | end | ||
| 261 | end | ||
| 262 | end | ||
| 263 | end | ||
| 264 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/faux_column.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/faux_column.rb new file mode 100644 index 0000000..84068de --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/faux_column.rb | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | class Index | ||
| 3 | # Instances of this class represent database columns and the stack of | ||
| 4 | # associations that lead from the base model to them. | ||
| 5 | # | ||
| 6 | # The name and stack are accessible through methods starting with __ to | ||
| 7 | # avoid conflicting with the method_missing calls that build the stack. | ||
| 8 | # | ||
| 9 | class FauxColumn | ||
| 10 | # Create a new column with a pre-defined stack. The top element in the | ||
| 11 | # stack will get shifted to be the name value. | ||
| 12 | # | ||
| 13 | def initialize(*stack) | ||
| 14 | @name = stack.pop | ||
| 15 | @stack = stack | ||
| 16 | end | ||
| 17 | |||
| 18 | def self.coerce(columns) | ||
| 19 | case columns | ||
| 20 | when Symbol, String | ||
| 21 | FauxColumn.new(columns) | ||
| 22 | when Array | ||
| 23 | columns.collect { |col| FauxColumn.coerce(col) } | ||
| 24 | when FauxColumn | ||
| 25 | columns | ||
| 26 | else | ||
| 27 | nil | ||
| 28 | end | ||
| 29 | end | ||
| 30 | |||
| 31 | # Can't use normal method name, as that could be an association or | ||
| 32 | # column name. | ||
| 33 | # | ||
| 34 | def __name | ||
| 35 | @name | ||
| 36 | end | ||
| 37 | |||
| 38 | # Can't use normal method name, as that could be an association or | ||
| 39 | # column name. | ||
| 40 | # | ||
| 41 | def __stack | ||
| 42 | @stack | ||
| 43 | end | ||
| 44 | |||
| 45 | # Returns true if the stack is empty *and* if the name is a string - | ||
| 46 | # which is an indication that of raw SQL, as opposed to a value from a | ||
| 47 | # table's column. | ||
| 48 | # | ||
| 49 | def is_string? | ||
| 50 | @name.is_a?(String) && @stack.empty? | ||
| 51 | end | ||
| 52 | |||
| 53 | # This handles any 'invalid' method calls and sets them as the name, | ||
| 54 | # and pushing the previous name into the stack. The object returns | ||
| 55 | # itself. | ||
| 56 | # | ||
| 57 | # If there's a single argument, it becomes the name, and the method | ||
| 58 | # symbol goes into the stack as well. Multiple arguments means new | ||
| 59 | # columns with the original stack and new names (from each argument) gets | ||
| 60 | # returned. | ||
| 61 | # | ||
| 62 | # Easier to explain with examples: | ||
| 63 | # | ||
| 64 | # col = FauxColumn.new :a, :b, :c | ||
| 65 | # col.__name #=> :c | ||
| 66 | # col.__stack #=> [:a, :b] | ||
| 67 | # | ||
| 68 | # col.whatever #=> col | ||
| 69 | # col.__name #=> :whatever | ||
| 70 | # col.__stack #=> [:a, :b, :c] | ||
| 71 | # | ||
| 72 | # col.something(:id) #=> col | ||
| 73 | # col.__name #=> :id | ||
| 74 | # col.__stack #=> [:a, :b, :c, :whatever, :something] | ||
| 75 | # | ||
| 76 | # cols = col.short(:x, :y, :z) | ||
| 77 | # cols[0].__name #=> :x | ||
| 78 | # cols[0].__stack #=> [:a, :b, :c, :whatever, :something, :short] | ||
| 79 | # cols[1].__name #=> :y | ||
| 80 | # cols[1].__stack #=> [:a, :b, :c, :whatever, :something, :short] | ||
| 81 | # cols[2].__name #=> :z | ||
| 82 | # cols[2].__stack #=> [:a, :b, :c, :whatever, :something, :short] | ||
| 83 | # | ||
| 84 | # Also, this allows method chaining to build up a relevant stack: | ||
| 85 | # | ||
| 86 | # col = FauxColumn.new :a, :b | ||
| 87 | # col.__name #=> :b | ||
| 88 | # col.__stack #=> [:a] | ||
| 89 | # | ||
| 90 | # col.one.two.three #=> col | ||
| 91 | # col.__name #=> :three | ||
| 92 | # col.__stack #=> [:a, :b, :one, :two] | ||
| 93 | # | ||
| 94 | def method_missing(method, *args) | ||
| 95 | @stack << @name | ||
| 96 | @name = method | ||
| 97 | |||
| 98 | if (args.empty?) | ||
| 99 | self | ||
| 100 | elsif (args.length == 1) | ||
| 101 | method_missing(args.first) | ||
| 102 | else | ||
| 103 | args.collect { |arg| | ||
| 104 | FauxColumn.new(@stack + [@name, arg]) | ||
| 105 | } | ||
| 106 | end | ||
| 107 | end | ||
| 108 | end | ||
| 109 | end | ||
| 110 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/rails_additions.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/rails_additions.rb new file mode 100644 index 0000000..c7db0a1 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/rails_additions.rb | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | module HashExcept | ||
| 3 | # Returns a new hash without the given keys. | ||
| 4 | def except(*keys) | ||
| 5 | rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys) | ||
| 6 | reject { |key,| rejected.include?(key) } | ||
| 7 | end | ||
| 8 | |||
| 9 | # Replaces the hash without only the given keys. | ||
| 10 | def except!(*keys) | ||
| 11 | replace(except(*keys)) | ||
| 12 | end | ||
| 13 | end | ||
| 14 | end | ||
| 15 | |||
| 16 | Hash.send( | ||
| 17 | :include, ThinkingSphinx::HashExcept | ||
| 18 | ) unless Hash.instance_methods.include?("except") | ||
| 19 | |||
| 20 | module ThinkingSphinx | ||
| 21 | module ArrayExtractOptions | ||
| 22 | def extract_options! | ||
| 23 | last.is_a?(::Hash) ? pop : {} | ||
| 24 | end | ||
| 25 | end | ||
| 26 | end | ||
| 27 | |||
| 28 | Array.send( | ||
| 29 | :include, ThinkingSphinx::ArrayExtractOptions | ||
| 30 | ) unless Array.instance_methods.include?("extract_options!") | ||
| 31 | |||
| 32 | module ThinkingSphinx | ||
| 33 | module AbstractQuotedTableName | ||
| 34 | def quote_table_name(name) | ||
| 35 | quote_column_name(name) | ||
| 36 | end | ||
| 37 | end | ||
| 38 | end | ||
| 39 | |||
| 40 | ActiveRecord::ConnectionAdapters::AbstractAdapter.send( | ||
| 41 | :include, ThinkingSphinx::AbstractQuotedTableName | ||
| 42 | ) unless ActiveRecord::ConnectionAdapters::AbstractAdapter.instance_methods.include?("quote_table_name") | ||
| 43 | |||
| 44 | module ThinkingSphinx | ||
| 45 | module MysqlQuotedTableName | ||
| 46 | def quote_table_name(name) #:nodoc: | ||
| 47 | quote_column_name(name).gsub('.', '`.`') | ||
| 48 | end | ||
| 49 | end | ||
| 50 | end | ||
| 51 | |||
| 52 | if ActiveRecord::ConnectionAdapters.constants.include?("MysqlAdapter") or ActiveRecord::Base.respond_to?(:jdbcmysql_connection) | ||
| 53 | adapter = ActiveRecord::ConnectionAdapters.const_get( | ||
| 54 | defined?(JRUBY_VERSION) ? :JdbcAdapter : :MysqlAdapter | ||
| 55 | ) | ||
| 56 | unless adapter.instance_methods.include?("quote_table_name") | ||
| 57 | adapter.send(:include, ThinkingSphinx::MysqlQuotedTableName) | ||
| 58 | end | ||
| 59 | end | ||
| 60 | |||
| 61 | module ThinkingSphinx | ||
| 62 | module ActiveRecordQuotedName | ||
| 63 | def quoted_table_name | ||
| 64 | self.connection.quote_table_name(self.table_name) | ||
| 65 | end | ||
| 66 | end | ||
| 67 | end | ||
| 68 | |||
| 69 | ActiveRecord::Base.extend( | ||
| 70 | ThinkingSphinx::ActiveRecordQuotedName | ||
| 71 | ) unless ActiveRecord::Base.respond_to?("quoted_table_name") | ||
| 72 | |||
| 73 | module ThinkingSphinx | ||
| 74 | module ActiveRecordStoreFullSTIClass | ||
| 75 | def store_full_sti_class | ||
| 76 | false | ||
| 77 | end | ||
| 78 | end | ||
| 79 | end | ||
| 80 | |||
| 81 | ActiveRecord::Base.extend( | ||
| 82 | ThinkingSphinx::ActiveRecordStoreFullSTIClass | ||
| 83 | ) unless ActiveRecord::Base.respond_to?(:store_full_sti_class) | ||
| 84 | |||
| 85 | module ThinkingSphinx | ||
| 86 | module ClassAttributeMethods | ||
| 87 | def cattr_reader(*syms) | ||
| 88 | syms.flatten.each do |sym| | ||
| 89 | next if sym.is_a?(Hash) | ||
| 90 | class_eval(<<-EOS, __FILE__, __LINE__) | ||
| 91 | unless defined? @@#{sym} | ||
| 92 | @@#{sym} = nil | ||
| 93 | end | ||
| 94 | |||
| 95 | def self.#{sym} | ||
| 96 | @@#{sym} | ||
| 97 | end | ||
| 98 | |||
| 99 | def #{sym} | ||
| 100 | @@#{sym} | ||
| 101 | end | ||
| 102 | EOS | ||
| 103 | end | ||
| 104 | end | ||
| 105 | |||
| 106 | def cattr_writer(*syms) | ||
| 107 | options = syms.extract_options! | ||
| 108 | syms.flatten.each do |sym| | ||
| 109 | class_eval(<<-EOS, __FILE__, __LINE__) | ||
| 110 | unless defined? @@#{sym} | ||
| 111 | @@#{sym} = nil | ||
| 112 | end | ||
| 113 | |||
| 114 | def self.#{sym}=(obj) | ||
| 115 | @@#{sym} = obj | ||
| 116 | end | ||
| 117 | |||
| 118 | #{" | ||
| 119 | def #{sym}=(obj) | ||
| 120 | @@#{sym} = obj | ||
| 121 | end | ||
| 122 | " unless options[:instance_writer] == false } | ||
| 123 | EOS | ||
| 124 | end | ||
| 125 | end | ||
| 126 | |||
| 127 | def cattr_accessor(*syms) | ||
| 128 | cattr_reader(*syms) | ||
| 129 | cattr_writer(*syms) | ||
| 130 | end | ||
| 131 | end | ||
| 132 | end | ||
| 133 | |||
| 134 | Class.extend( | ||
| 135 | ThinkingSphinx::ClassAttributeMethods | ||
| 136 | ) unless Class.respond_to?(:cattr_reader) | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb new file mode 100644 index 0000000..d476787 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb | |||
| @@ -0,0 +1,780 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | # Once you've got those indexes in and built, this is the stuff that | ||
| 3 | # matters - how to search! This class provides a generic search | ||
| 4 | # interface - which you can use to search all your indexed models at once. | ||
| 5 | # Most times, you will just want a specific model's results - to search and | ||
| 6 | # search_for_ids methods will do the job in exactly the same manner when | ||
| 7 | # called from a model. | ||
| 8 | # | ||
| 9 | class Search | ||
| 10 | GlobalFacetOptions = { | ||
| 11 | :all_attributes => false, | ||
| 12 | :class_facet => true | ||
| 13 | } | ||
| 14 | |||
| 15 | class << self | ||
| 16 | # Searches for results that match the parameters provided. Will only | ||
| 17 | # return the ids for the matching objects. See #search for syntax | ||
| 18 | # examples. | ||
| 19 | # | ||
| 20 | # Note that this only searches the Sphinx index, with no ActiveRecord | ||
| 21 | # queries. Thus, if your index is not in sync with the database, this | ||
| 22 | # method may return ids that no longer exist there. | ||
| 23 | # | ||
| 24 | def search_for_ids(*args) | ||
| 25 | results, client = search_results(*args.clone) | ||
| 26 | |||
| 27 | options = args.extract_options! | ||
| 28 | page = options[:page] ? options[:page].to_i : 1 | ||
| 29 | |||
| 30 | ThinkingSphinx::Collection.ids_from_results(results, page, client.limit, options) | ||
| 31 | end | ||
| 32 | |||
| 33 | # Searches through the Sphinx indexes for relevant matches. There's | ||
| 34 | # various ways to search, sort, group and filter - which are covered | ||
| 35 | # below. | ||
| 36 | # | ||
| 37 | # Also, if you have WillPaginate installed, the search method can be used | ||
| 38 | # just like paginate. The same parameters - :page and :per_page - work as | ||
| 39 | # expected, and the returned result set can be used by the will_paginate | ||
| 40 | # helper. | ||
| 41 | # | ||
| 42 | # == Basic Searching | ||
| 43 | # | ||
| 44 | # The simplest way of searching is straight text. | ||
| 45 | # | ||
| 46 | # ThinkingSphinx::Search.search "pat" | ||
| 47 | # ThinkingSphinx::Search.search "google" | ||
| 48 | # User.search "pat", :page => (params[:page] || 1) | ||
| 49 | # Article.search "relevant news issue of the day" | ||
| 50 | # | ||
| 51 | # If you specify :include, like in an #find call, this will be respected | ||
| 52 | # when loading the relevant models from the search results. | ||
| 53 | # | ||
| 54 | # User.search "pat", :include => :posts | ||
| 55 | # | ||
| 56 | # == Match Modes | ||
| 57 | # | ||
| 58 | # Sphinx supports 5 different matching modes. By default Thinking Sphinx | ||
| 59 | # uses :all, which unsurprisingly requires all the supplied search terms | ||
| 60 | # to match a result. | ||
| 61 | # | ||
| 62 | # Alternative modes include: | ||
| 63 | # | ||
| 64 | # User.search "pat allan", :match_mode => :any | ||
| 65 | # User.search "pat allan", :match_mode => :phrase | ||
| 66 | # User.search "pat | allan", :match_mode => :boolean | ||
| 67 | # User.search "@name pat | @username pat", :match_mode => :extended | ||
| 68 | # | ||
| 69 | # Any will find results with any of the search terms. Phrase treats the search | ||
| 70 | # terms a single phrase instead of individual words. Boolean and extended allow | ||
| 71 | # for more complex query syntax, refer to the sphinx documentation for further | ||
| 72 | # details. | ||
| 73 | # | ||
| 74 | # == Weighting | ||
| 75 | # | ||
| 76 | # Sphinx has support for weighting, where matches in one field can be considered | ||
| 77 | # more important than in another. Weights are integers, with 1 as the default. | ||
| 78 | # They can be set per-search like this: | ||
| 79 | # | ||
| 80 | # User.search "pat allan", :field_weights => { :alias => 4, :aka => 2 } | ||
| 81 | # | ||
| 82 | # If you're searching multiple models, you can set per-index weights: | ||
| 83 | # | ||
| 84 | # ThinkingSphinx::Search.search "pat", :index_weights => { User => 10 } | ||
| 85 | # | ||
| 86 | # See http://sphinxsearch.com/doc.html#weighting for further details. | ||
| 87 | # | ||
| 88 | # == Searching by Fields | ||
| 89 | # | ||
| 90 | # If you want to step it up a level, you can limit your search terms to | ||
| 91 | # specific fields: | ||
| 92 | # | ||
| 93 | # User.search :conditions => {:name => "pat"} | ||
| 94 | # | ||
| 95 | # This uses Sphinx's extended match mode, unless you specify a different | ||
| 96 | # match mode explicitly (but then this way of searching won't work). Also | ||
| 97 | # note that you don't need to put in a search string. | ||
| 98 | # | ||
| 99 | # == Searching by Attributes | ||
| 100 | # | ||
| 101 | # Also known as filters, you can limit your searches to documents that | ||
| 102 | # have specific values for their attributes. There are three ways to do | ||
| 103 | # this. The first two techniques work in all scenarios - using the :with | ||
| 104 | # or :with_all options. | ||
| 105 | # | ||
| 106 | # ThinkingSphinx::Search.search :with => {:tag_ids => 10} | ||
| 107 | # ThinkingSphinx::Search.search :with => {:tag_ids => [10,12]} | ||
| 108 | # ThinkingSphinx::Search.search :with_all => {:tag_ids => [10,12]} | ||
| 109 | # | ||
| 110 | # The first :with search will match records with a tag_id attribute of 10. | ||
| 111 | # The second :with will match records with a tag_id attribute of 10 OR 12. | ||
| 112 | # If you need to find records that are tagged with ids 10 AND 12, you | ||
| 113 | # will need to use the :with_all search parameter. This is particuarly | ||
| 114 | # useful in conjunction with Multi Value Attributes (MVAs). | ||
| 115 | # | ||
| 116 | # The third filtering technique is only viable if you're searching with a | ||
| 117 | # specific model (not multi-model searching). With a single model, | ||
| 118 | # Thinking Sphinx can figure out what attributes and fields are available, | ||
| 119 | # so you can put it all in the :conditions hash, and it will sort it out. | ||
| 120 | # | ||
| 121 | # Node.search :conditions => {:parent_id => 10} | ||
| 122 | # | ||
| 123 | # Filters can be single values, arrays of values, or ranges. | ||
| 124 | # | ||
| 125 | # Article.search "East Timor", :conditions => {:rating => 3..5} | ||
| 126 | # | ||
| 127 | # == Excluding by Attributes | ||
| 128 | # | ||
| 129 | # Sphinx also supports negative filtering - where the filters are of | ||
| 130 | # attribute values to exclude. This is done with the :without option: | ||
| 131 | # | ||
| 132 | # User.search :without => {:role_id => 1} | ||
| 133 | # | ||
| 134 | # == Excluding by Primary Key | ||
| 135 | # | ||
| 136 | # There is a shortcut to exclude records by their ActiveRecord primary key: | ||
| 137 | # | ||
| 138 | # User.search :without_ids => 1 | ||
| 139 | # | ||
| 140 | # Pass an array or a single value. | ||
| 141 | # | ||
| 142 | # The primary key must be an integer as a negative filter is used. Note | ||
| 143 | # that for multi-model search, an id may occur in more than one model. | ||
| 144 | # | ||
| 145 | # == Infix (Star) Searching | ||
| 146 | # | ||
| 147 | # By default, Sphinx uses English stemming, e.g. matching "shoes" if you | ||
| 148 | # search for "shoe". It won't find "Melbourne" if you search for | ||
| 149 | # "elbourn", though. | ||
| 150 | # | ||
| 151 | # Enable infix searching by something like this in config/sphinx.yml: | ||
| 152 | # | ||
| 153 | # development: | ||
| 154 | # enable_star: 1 | ||
| 155 | # min_infix_length: 2 | ||
| 156 | # | ||
| 157 | # Note that this will make indexing take longer. | ||
| 158 | # | ||
| 159 | # With those settings (and after reindexing), wildcard asterisks can be used | ||
| 160 | # in queries: | ||
| 161 | # | ||
| 162 | # Location.search "*elbourn*" | ||
| 163 | # | ||
| 164 | # To automatically add asterisks around every token (but not operators), | ||
| 165 | # pass the :star option: | ||
| 166 | # | ||
| 167 | # Location.search "elbourn -ustrali", :star => true, :match_mode => :boolean | ||
| 168 | # | ||
| 169 | # This would become "*elbourn* -*ustrali*". The :star option only adds the | ||
| 170 | # asterisks. You need to make the config/sphinx.yml changes yourself. | ||
| 171 | # | ||
| 172 | # By default, the tokens are assumed to match the regular expression /\w+/u. | ||
| 173 | # If you've modified the charset_table, pass another regular expression, e.g. | ||
| 174 | # | ||
| 175 | # User.search("oo@bar.c", :star => /[\w@.]+/u) | ||
| 176 | # | ||
| 177 | # to search for "*oo@bar.c*" and not "*oo*@*bar*.*c*". | ||
| 178 | # | ||
| 179 | # == Sorting | ||
| 180 | # | ||
| 181 | # Sphinx can only sort by attributes, so generally you will need to avoid | ||
| 182 | # using field names in your :order option. However, if you're searching | ||
| 183 | # on a single model, and have specified some fields as sortable, you can | ||
| 184 | # use those field names and Thinking Sphinx will interpret accordingly. | ||
| 185 | # Remember: this will only happen for single-model searches, and only | ||
| 186 | # through the :order option. | ||
| 187 | # | ||
| 188 | # Location.search "Melbourne", :order => :state | ||
| 189 | # User.search :conditions => {:role_id => 2}, :order => "name ASC" | ||
| 190 | # | ||
| 191 | # Keep in mind that if you use a string, you *must* specify the direction | ||
| 192 | # (ASC or DESC) else Sphinx won't return any results. If you use a symbol | ||
| 193 | # then Thinking Sphinx assumes ASC, but if you wish to state otherwise, | ||
| 194 | # use the :sort_mode option: | ||
| 195 | # | ||
| 196 | # Location.search "Melbourne", :order => :state, :sort_mode => :desc | ||
| 197 | # | ||
| 198 | # Of course, there are other sort modes - check out the Sphinx | ||
| 199 | # documentation[http://sphinxsearch.com/doc.html] for that level of | ||
| 200 | # detail though. | ||
| 201 | # | ||
| 202 | # If desired, you can sort by a column in your model instead of a sphinx | ||
| 203 | # field or attribute. This sort only applies to the current page, so is | ||
| 204 | # most useful when performing a search with a single page of results. | ||
| 205 | # | ||
| 206 | # User.search("pat", :sql_order => "name") | ||
| 207 | # | ||
| 208 | # == Grouping | ||
| 209 | # | ||
| 210 | # For this you can use the group_by, group_clause and group_function | ||
| 211 | # options - which are all directly linked to Sphinx's expectations. No | ||
| 212 | # magic from Thinking Sphinx. It can get a little tricky, so make sure | ||
| 213 | # you read all the relevant | ||
| 214 | # documentation[http://sphinxsearch.com/doc.html#clustering] first. | ||
| 215 | # | ||
| 216 | # Grouping is done via three parameters within the options hash | ||
| 217 | # * <tt>:group_function</tt> determines the way grouping is done | ||
| 218 | # * <tt>:group_by</tt> determines the field which is used for grouping | ||
| 219 | # * <tt>:group_clause</tt> determines the sorting order | ||
| 220 | # | ||
| 221 | # === group_function | ||
| 222 | # | ||
| 223 | # Valid values for :group_function are | ||
| 224 | # * <tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>, <tt>:year</tt> - Grouping is done by the respective timeframes. | ||
| 225 | # * <tt>:attr</tt>, <tt>:attrpair</tt> - Grouping is done by the specified attributes(s) | ||
| 226 | # | ||
| 227 | # === group_by | ||
| 228 | # | ||
| 229 | # This parameter denotes the field by which grouping is done. Note that the | ||
| 230 | # specified field must be a sphinx attribute or index. | ||
| 231 | # | ||
| 232 | # === group_clause | ||
| 233 | # | ||
| 234 | # This determines the sorting order of the groups. In a grouping search, | ||
| 235 | # the matches within a group will sorted by the <tt>:sort_mode</tt> and <tt>:order</tt> parameters. | ||
| 236 | # The group matches themselves however, will be sorted by <tt>:group_clause</tt>. | ||
| 237 | # | ||
| 238 | # The syntax for this is the same as an order parameter in extended sort mode. | ||
| 239 | # Namely, you can specify an SQL-like sort expression with up to 5 attributes | ||
| 240 | # (including internal attributes), eg: "@relevance DESC, price ASC, @id DESC" | ||
| 241 | # | ||
| 242 | # === Grouping by timestamp | ||
| 243 | # | ||
| 244 | # Timestamp grouping groups off items by the day, week, month or year of the | ||
| 245 | # attribute given. In order to do this you need to define a timestamp attribute, | ||
| 246 | # which pretty much looks like the standard defintion for any attribute. | ||
| 247 | # | ||
| 248 | # define_index do | ||
| 249 | # # | ||
| 250 | # # All your other stuff | ||
| 251 | # # | ||
| 252 | # has :created_at | ||
| 253 | # end | ||
| 254 | # | ||
| 255 | # When you need to fire off your search, it'll go something to the tune of | ||
| 256 | # | ||
| 257 | # Fruit.search "apricot", :group_function => :day, :group_by => 'created_at' | ||
| 258 | # | ||
| 259 | # The <tt>@groupby</tt> special attribute will contain the date for that group. | ||
| 260 | # Depending on the <tt>:group_function</tt> parameter, the date format will be | ||
| 261 | # | ||
| 262 | # * <tt>:day</tt> - YYYYMMDD | ||
| 263 | # * <tt>:week</tt> - YYYYNNN (NNN is the first day of the week in question, | ||
| 264 | # counting from the start of the year ) | ||
| 265 | # * <tt>:month</tt> - YYYYMM | ||
| 266 | # * <tt>:year</tt> - YYYY | ||
| 267 | # | ||
| 268 | # | ||
| 269 | # === Grouping by attribute | ||
| 270 | # | ||
| 271 | # The syntax is the same as grouping by timestamp, except for the fact that the | ||
| 272 | # <tt>:group_function</tt> parameter is changed | ||
| 273 | # | ||
| 274 | # Fruit.search "apricot", :group_function => :attr, :group_by => 'size' | ||
| 275 | # | ||
| 276 | # | ||
| 277 | # == Geo/Location Searching | ||
| 278 | # | ||
| 279 | # Sphinx - and therefore Thinking Sphinx - has the facility to search | ||
| 280 | # around a geographical point, using a given latitude and longitude. To | ||
| 281 | # take advantage of this, you will need to have both of those values in | ||
| 282 | # attributes. To search with that point, you can then use one of the | ||
| 283 | # following syntax examples: | ||
| 284 | # | ||
| 285 | # Address.search "Melbourne", :geo => [1.4, -2.217], :order => "@geodist asc" | ||
| 286 | # Address.search "Australia", :geo => [-0.55, 3.108], :order => "@geodist asc" | ||
| 287 | # :latitude_attr => "latit", :longitude_attr => "longit" | ||
| 288 | # | ||
| 289 | # The first example applies when your latitude and longitude attributes | ||
| 290 | # are named any of lat, latitude, lon, long or longitude. If that's not | ||
| 291 | # the case, you will need to explicitly state them in your search, _or_ | ||
| 292 | # you can do so in your model: | ||
| 293 | # | ||
| 294 | # define_index do | ||
| 295 | # has :latit # Float column, stored in radians | ||
| 296 | # has :longit # Float column, stored in radians | ||
| 297 | # | ||
| 298 | # set_property :latitude_attr => "latit" | ||
| 299 | # set_property :longitude_attr => "longit" | ||
| 300 | # end | ||
| 301 | # | ||
| 302 | # Now, geo-location searching really only has an affect if you have a | ||
| 303 | # filter, sort or grouping clause related to it - otherwise it's just a | ||
| 304 | # normal search, and _will not_ return a distance value otherwise. To | ||
| 305 | # make use of the positioning difference, use the special attribute | ||
| 306 | # "@geodist" in any of your filters or sorting or grouping clauses. | ||
| 307 | # | ||
| 308 | # And don't forget - both the latitude and longitude you use in your | ||
| 309 | # search, and the values in your indexes, need to be stored as a float in radians, | ||
| 310 | # _not_ degrees. Keep in mind that if you do this conversion in SQL | ||
| 311 | # you will need to explicitly declare a column type of :float. | ||
| 312 | # | ||
| 313 | # define_index do | ||
| 314 | # has 'RADIANS(lat)', :as => :lat, :type => :float | ||
| 315 | # # ... | ||
| 316 | # end | ||
| 317 | # | ||
| 318 | # Once you've got your results set, you can access the distances as | ||
| 319 | # follows: | ||
| 320 | # | ||
| 321 | # @results.each_with_geodist do |result, distance| | ||
| 322 | # # ... | ||
| 323 | # end | ||
| 324 | # | ||
| 325 | # The distance value is returned as a float, representing the distance in | ||
| 326 | # metres. | ||
| 327 | # | ||
| 328 | # == Handling a Stale Index | ||
| 329 | # | ||
| 330 | # Especially if you don't use delta indexing, you risk having records in the | ||
| 331 | # Sphinx index that are no longer in the database. By default, those will simply | ||
| 332 | # come back as nils: | ||
| 333 | # | ||
| 334 | # >> pat_user.delete | ||
| 335 | # >> User.search("pat") | ||
| 336 | # Sphinx Result: [1,2] | ||
| 337 | # => [nil, <#User id: 2>] | ||
| 338 | # | ||
| 339 | # (If you search across multiple models, you'll get ActiveRecord::RecordNotFound.) | ||
| 340 | # | ||
| 341 | # You can simply Array#compact these results or handle the nils in some other way, but | ||
| 342 | # Sphinx will still report two results, and the missing records may upset your layout. | ||
| 343 | # | ||
| 344 | # If you pass :retry_stale => true to a single-model search, missing records will | ||
| 345 | # cause Thinking Sphinx to retry the query but excluding those records. Since search | ||
| 346 | # is paginated, the new search could potentially include missing records as well, so by | ||
| 347 | # default Thinking Sphinx will retry three times. Pass :retry_stale => 5 to retry five | ||
| 348 | # times, and so on. If there are still missing ids on the last retry, they are | ||
| 349 | # shown as nils. | ||
| 350 | # | ||
| 351 | def search(*args) | ||
| 352 | query = args.clone # an array | ||
| 353 | options = query.extract_options! | ||
| 354 | |||
| 355 | retry_search_on_stale_index(query, options) do | ||
| 356 | results, client = search_results(*(query + [options])) | ||
| 357 | |||
| 358 | ::ActiveRecord::Base.logger.error( | ||
| 359 | "Sphinx Error: #{results[:error]}" | ||
| 360 | ) if results[:error] | ||
| 361 | |||
| 362 | klass = options[:class] | ||
| 363 | page = options[:page] ? options[:page].to_i : 1 | ||
| 364 | |||
| 365 | ThinkingSphinx::Collection.create_from_results(results, page, client.limit, options) | ||
| 366 | end | ||
| 367 | end | ||
| 368 | |||
| 369 | def retry_search_on_stale_index(query, options, &block) | ||
| 370 | stale_ids = [] | ||
| 371 | stale_retries_left = case options[:retry_stale] | ||
| 372 | when true | ||
| 373 | 3 # default to three retries | ||
| 374 | when nil, false | ||
| 375 | 0 # no retries | ||
| 376 | else options[:retry_stale].to_i | ||
| 377 | end | ||
| 378 | begin | ||
| 379 | # Passing this in an option so Collection.create_from_results can see it. | ||
| 380 | # It should only raise on stale records if there are any retries left. | ||
| 381 | options[:raise_on_stale] = stale_retries_left > 0 | ||
| 382 | block.call | ||
| 383 | # If ThinkingSphinx::Collection.create_from_results found records in Sphinx but not | ||
| 384 | # in the DB and the :raise_on_stale option is set, this exception is raised. We retry | ||
| 385 | # a limited number of times, excluding the stale ids from the search. | ||
| 386 | rescue StaleIdsException => e | ||
| 387 | stale_retries_left -= 1 | ||
| 388 | |||
| 389 | stale_ids |= e.ids # For logging | ||
| 390 | options[:without_ids] = Array(options[:without_ids]) | e.ids # Actual exclusion | ||
| 391 | |||
| 392 | tries = stale_retries_left | ||
| 393 | ::ActiveRecord::Base.logger.debug("Sphinx Stale Ids (%s %s left): %s" % [ | ||
| 394 | tries, (tries==1 ? 'try' : 'tries'), stale_ids.join(', ') | ||
| 395 | ]) | ||
| 396 | |||
| 397 | retry | ||
| 398 | end | ||
| 399 | end | ||
| 400 | |||
| 401 | def count(*args) | ||
| 402 | results, client = search_results(*args.clone) | ||
| 403 | results[:total_found] || 0 | ||
| 404 | end | ||
| 405 | |||
| 406 | # Checks if a document with the given id exists within a specific index. | ||
| 407 | # Expected parameters: | ||
| 408 | # | ||
| 409 | # - ID of the document | ||
| 410 | # - Index to check within | ||
| 411 | # - Options hash (defaults to {}) | ||
| 412 | # | ||
| 413 | # Example: | ||
| 414 | # | ||
| 415 | # ThinkingSphinx::Search.search_for_id(10, "user_core", :class => User) | ||
| 416 | # | ||
| 417 | def search_for_id(*args) | ||
| 418 | options = args.extract_options! | ||
| 419 | client = client_from_options options | ||
| 420 | |||
| 421 | query, filters = search_conditions( | ||
| 422 | options[:class], options[:conditions] || {} | ||
| 423 | ) | ||
| 424 | client.filters += filters | ||
| 425 | client.match_mode = :extended unless query.empty? | ||
| 426 | client.id_range = args.first..args.first | ||
| 427 | |||
| 428 | begin | ||
| 429 | return client.query(query, args[1])[:matches].length > 0 | ||
| 430 | rescue Errno::ECONNREFUSED => err | ||
| 431 | raise ThinkingSphinx::ConnectionError, "Connection to Sphinx Daemon (searchd) failed." | ||
| 432 | end | ||
| 433 | end | ||
| 434 | |||
| 435 | # Model.facets *args | ||
| 436 | # ThinkingSphinx::Search.facets *args | ||
| 437 | # ThinkingSphinx::Search.facets *args, :all_attributes => true | ||
| 438 | # ThinkingSphinx::Search.facets *args, :class_facet => false | ||
| 439 | # | ||
| 440 | def facets(*args) | ||
| 441 | options = args.extract_options! | ||
| 442 | |||
| 443 | if options[:class] | ||
| 444 | facets_for_model options[:class], args, options | ||
| 445 | else | ||
| 446 | facets_for_all_models args, options | ||
| 447 | end | ||
| 448 | end | ||
| 449 | |||
| 450 | private | ||
| 451 | |||
| 452 | # This method handles the common search functionality, and returns both | ||
| 453 | # the result hash and the client. Not super elegant, but it'll do for | ||
| 454 | # the moment. | ||
| 455 | # | ||
| 456 | def search_results(*args) | ||
| 457 | options = args.extract_options! | ||
| 458 | query = args.join(' ') | ||
| 459 | client = client_from_options options | ||
| 460 | |||
| 461 | query = star_query(query, options[:star]) if options[:star] | ||
| 462 | |||
| 463 | extra_query, filters = search_conditions( | ||
| 464 | options[:class], options[:conditions] || {} | ||
| 465 | ) | ||
| 466 | client.filters += filters | ||
| 467 | client.match_mode = :extended unless extra_query.empty? | ||
| 468 | query = [query, extra_query].join(' ') | ||
| 469 | query.strip! # Because "" and " " are not equivalent | ||
| 470 | |||
| 471 | set_sort_options! client, options | ||
| 472 | |||
| 473 | client.limit = options[:per_page].to_i if options[:per_page] | ||
| 474 | page = options[:page] ? options[:page].to_i : 1 | ||
| 475 | page = 1 if page <= 0 | ||
| 476 | client.offset = (page - 1) * client.limit | ||
| 477 | |||
| 478 | begin | ||
| 479 | ::ActiveRecord::Base.logger.debug "Sphinx: #{query}" | ||
| 480 | results = client.query query | ||
| 481 | ::ActiveRecord::Base.logger.debug "Sphinx Result: #{results[:matches].collect{|m| m[:attributes]["sphinx_internal_id"]}.inspect}" | ||
| 482 | rescue Errno::ECONNREFUSED => err | ||
| 483 | raise ThinkingSphinx::ConnectionError, "Connection to Sphinx Daemon (searchd) failed." | ||
| 484 | end | ||
| 485 | |||
| 486 | return results, client | ||
| 487 | end | ||
| 488 | |||
| 489 | # Set all the appropriate settings for the client, using the provided | ||
| 490 | # options hash. | ||
| 491 | # | ||
| 492 | def client_from_options(options = {}) | ||
| 493 | config = ThinkingSphinx::Configuration.instance | ||
| 494 | client = Riddle::Client.new config.address, config.port | ||
| 495 | klass = options[:class] | ||
| 496 | index_options = klass ? klass.sphinx_index_options : {} | ||
| 497 | |||
| 498 | # The Riddle default is per-query max_matches=1000. If we set the | ||
| 499 | # per-server max to a smaller value in sphinx.yml, we need to override | ||
| 500 | # the Riddle default or else we get search errors like | ||
| 501 | # "per-query max_matches=1000 out of bounds (per-server max_matches=200)" | ||
| 502 | if per_server_max_matches = config.configuration.searchd.max_matches | ||
| 503 | options[:max_matches] ||= per_server_max_matches | ||
| 504 | end | ||
| 505 | |||
| 506 | # Turn :index_weights => { "foo" => 2, User => 1 } | ||
| 507 | # into :index_weights => { "foo" => 2, "user_core" => 1, "user_delta" => 1 } | ||
| 508 | if iw = options[:index_weights] | ||
| 509 | options[:index_weights] = iw.inject({}) do |hash, (index,weight)| | ||
| 510 | if index.is_a?(Class) | ||
| 511 | name = ThinkingSphinx::Index.name(index) | ||
| 512 | hash["#{name}_core"] = weight | ||
| 513 | hash["#{name}_delta"] = weight | ||
| 514 | else | ||
| 515 | hash[index] = weight | ||
| 516 | end | ||
| 517 | hash | ||
| 518 | end | ||
| 519 | end | ||
| 520 | |||
| 521 | [ | ||
| 522 | :max_matches, :match_mode, :sort_mode, :sort_by, :id_range, | ||
| 523 | :group_by, :group_function, :group_clause, :group_distinct, :cut_off, | ||
| 524 | :retry_count, :retry_delay, :index_weights, :rank_mode, | ||
| 525 | :max_query_time, :field_weights, :filters, :anchor, :limit | ||
| 526 | ].each do |key| | ||
| 527 | client.send( | ||
| 528 | key.to_s.concat("=").to_sym, | ||
| 529 | options[key] || index_options[key] || client.send(key) | ||
| 530 | ) | ||
| 531 | end | ||
| 532 | |||
| 533 | options[:classes] = [klass] if klass | ||
| 534 | |||
| 535 | client.anchor = anchor_conditions(klass, options) || {} if client.anchor.empty? | ||
| 536 | |||
| 537 | client.filters << Riddle::Client::Filter.new( | ||
| 538 | "sphinx_deleted", [0] | ||
| 539 | ) | ||
| 540 | |||
| 541 | # class filters | ||
| 542 | client.filters << Riddle::Client::Filter.new( | ||
| 543 | "class_crc", options[:classes].collect { |k| k.to_crc32s }.flatten | ||
| 544 | ) if options[:classes] | ||
| 545 | |||
| 546 | # normal attribute filters | ||
| 547 | client.filters += options[:with].collect { |attr,val| | ||
| 548 | Riddle::Client::Filter.new attr.to_s, filter_value(val) | ||
| 549 | } if options[:with] | ||
| 550 | |||
| 551 | # exclusive attribute filters | ||
| 552 | client.filters += options[:without].collect { |attr,val| | ||
| 553 | Riddle::Client::Filter.new attr.to_s, filter_value(val), true | ||
| 554 | } if options[:without] | ||
| 555 | |||
| 556 | # every-match attribute filters | ||
| 557 | client.filters += options[:with_all].collect { |attr,vals| | ||
| 558 | Array(vals).collect { |val| | ||
| 559 | Riddle::Client::Filter.new attr.to_s, filter_value(val) | ||
| 560 | } | ||
| 561 | }.flatten if options[:with_all] | ||
| 562 | |||
| 563 | # exclusive attribute filter on primary key | ||
| 564 | client.filters += Array(options[:without_ids]).collect { |id| | ||
| 565 | Riddle::Client::Filter.new 'sphinx_internal_id', filter_value(id), true | ||
| 566 | } if options[:without_ids] | ||
| 567 | |||
| 568 | client | ||
| 569 | end | ||
| 570 | |||
| 571 | def star_query(query, custom_token = nil) | ||
| 572 | token = custom_token.is_a?(Regexp) ? custom_token : /\w+/u | ||
| 573 | |||
| 574 | query.gsub(/("#{token}(.*?#{token})?"|(?![!-])#{token})/u) do | ||
| 575 | pre, proper, post = $`, $&, $' | ||
| 576 | is_operator = pre.match(%r{(\W|^)[@~/]\Z}) # E.g. "@foo", "/2", "~3", but not as part of a token | ||
| 577 | is_quote = proper.starts_with?('"') && proper.ends_with?('"') # E.g. "foo bar", with quotes | ||
| 578 | has_star = pre.ends_with?("*") || post.starts_with?("*") | ||
| 579 | if is_operator || is_quote || has_star | ||
| 580 | proper | ||
| 581 | else | ||
| 582 | "*#{proper}*" | ||
| 583 | end | ||
| 584 | end | ||
| 585 | end | ||
| 586 | |||
| 587 | def filter_value(value) | ||
| 588 | case value | ||
| 589 | when Range | ||
| 590 | value.first.is_a?(Time) ? timestamp(value.first)..timestamp(value.last) : value | ||
| 591 | when Array | ||
| 592 | value.collect { |val| val.is_a?(Time) ? timestamp(val) : val } | ||
| 593 | else | ||
| 594 | Array(value) | ||
| 595 | end | ||
| 596 | end | ||
| 597 | |||
| 598 | # Returns the integer timestamp for a Time object. | ||
| 599 | # | ||
| 600 | # If using Rails 2.1+, need to handle timezones to translate them back to | ||
| 601 | # UTC, as that's what datetimes will be stored as by MySQL. | ||
| 602 | # | ||
| 603 | # in_time_zone is a method that was added for the timezone support in | ||
| 604 | # Rails 2.1, which is why it's used for testing. I'm sure there's better | ||
| 605 | # ways, but this does the job. | ||
| 606 | # | ||
| 607 | def timestamp(value) | ||
| 608 | value.respond_to?(:in_time_zone) ? value.utc.to_i : value.to_i | ||
| 609 | end | ||
| 610 | |||
| 611 | # Translate field and attribute conditions to the relevant search string | ||
| 612 | # and filters. | ||
| 613 | # | ||
| 614 | def search_conditions(klass, conditions={}) | ||
| 615 | attributes = klass ? klass.sphinx_indexes.collect { |index| | ||
| 616 | index.attributes.collect { |attrib| attrib.unique_name } | ||
| 617 | }.flatten : [] | ||
| 618 | |||
| 619 | search_string = [] | ||
| 620 | filters = [] | ||
| 621 | |||
| 622 | conditions.each do |key,val| | ||
| 623 | if attributes.include?(key.to_sym) | ||
| 624 | filters << Riddle::Client::Filter.new( | ||
| 625 | key.to_s, filter_value(val) | ||
| 626 | ) | ||
| 627 | else | ||
| 628 | search_string << "@#{key} #{val}" | ||
| 629 | end | ||
| 630 | end | ||
| 631 | |||
| 632 | return search_string.join(' '), filters | ||
| 633 | end | ||
| 634 | |||
| 635 | # Return the appropriate latitude and longitude values, depending on | ||
| 636 | # whether the relevant attributes have been defined, and also whether | ||
| 637 | # there's actually any values. | ||
| 638 | # | ||
| 639 | def anchor_conditions(klass, options) | ||
| 640 | attributes = klass ? klass.sphinx_indexes.collect { |index| | ||
| 641 | index.attributes.collect { |attrib| attrib.unique_name } | ||
| 642 | }.flatten : [] | ||
| 643 | |||
| 644 | lat_attr = klass ? klass.sphinx_indexes.collect { |index| | ||
| 645 | index.options[:latitude_attr] | ||
| 646 | }.compact.first : nil | ||
| 647 | |||
| 648 | lon_attr = klass ? klass.sphinx_indexes.collect { |index| | ||
| 649 | index.options[:longitude_attr] | ||
| 650 | }.compact.first : nil | ||
| 651 | |||
| 652 | lat_attr = options[:latitude_attr] if options[:latitude_attr] | ||
| 653 | lat_attr ||= :lat if attributes.include?(:lat) | ||
| 654 | lat_attr ||= :latitude if attributes.include?(:latitude) | ||
| 655 | |||
| 656 | lon_attr = options[:longitude_attr] if options[:longitude_attr] | ||
| 657 | lon_attr ||= :lng if attributes.include?(:lng) | ||
| 658 | lon_attr ||= :lon if attributes.include?(:lon) | ||
| 659 | lon_attr ||= :long if attributes.include?(:long) | ||
| 660 | lon_attr ||= :longitude if attributes.include?(:longitude) | ||
| 661 | |||
| 662 | lat = options[:lat] | ||
| 663 | lon = options[:lon] | ||
| 664 | |||
| 665 | if options[:geo] | ||
| 666 | lat = options[:geo].first | ||
| 667 | lon = options[:geo].last | ||
| 668 | end | ||
| 669 | |||
| 670 | lat && lon ? { | ||
| 671 | :latitude_attribute => lat_attr.to_s, | ||
| 672 | :latitude => lat, | ||
| 673 | :longitude_attribute => lon_attr.to_s, | ||
| 674 | :longitude => lon | ||
| 675 | } : nil | ||
| 676 | end | ||
| 677 | |||
| 678 | # Set the sort options using the :order key as well as the appropriate | ||
| 679 | # Riddle settings. | ||
| 680 | # | ||
| 681 | def set_sort_options!(client, options) | ||
| 682 | klass = options[:class] | ||
| 683 | fields = klass ? klass.sphinx_indexes.collect { |index| | ||
| 684 | index.fields.collect { |field| field.unique_name } | ||
| 685 | }.flatten : [] | ||
| 686 | index_options = klass ? klass.sphinx_index_options : {} | ||
| 687 | |||
| 688 | order = options[:order] || index_options[:order] | ||
| 689 | case order | ||
| 690 | when Symbol | ||
| 691 | client.sort_mode = :attr_asc if client.sort_mode == :relevance || client.sort_mode.nil? | ||
| 692 | if fields.include?(order) | ||
| 693 | client.sort_by = order.to_s.concat("_sort") | ||
| 694 | else | ||
| 695 | client.sort_by = order.to_s | ||
| 696 | end | ||
| 697 | when String | ||
| 698 | client.sort_mode = :extended | ||
| 699 | client.sort_by = sorted_fields_to_attributes(order, fields) | ||
| 700 | else | ||
| 701 | # do nothing | ||
| 702 | end | ||
| 703 | |||
| 704 | client.sort_mode = :attr_asc if client.sort_mode == :asc | ||
| 705 | client.sort_mode = :attr_desc if client.sort_mode == :desc | ||
| 706 | end | ||
| 707 | |||
| 708 | # Search through a collection of fields and translate any appearances | ||
| 709 | # of them in a string to their attribute equivalent for sorting. | ||
| 710 | # | ||
| 711 | def sorted_fields_to_attributes(string, fields) | ||
| 712 | fields.each { |field| | ||
| 713 | string.gsub!(/(^|\s)#{field}(,?\s|$)/) { |match| | ||
| 714 | match.gsub field.to_s, field.to_s.concat("_sort") | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 718 | string | ||
| 719 | end | ||
| 720 | |||
| 721 | def facets_for_model(klass, args, options) | ||
| 722 | hash = ThinkingSphinx::FacetCollection.new args + [options] | ||
| 723 | options = options.clone.merge! :group_function => :attr | ||
| 724 | |||
| 725 | klass.sphinx_facets.inject(hash) do |hash, facet| | ||
| 726 | unless facet.name == :class && !options[:class_facet] | ||
| 727 | options[:group_by] = facet.attribute_name | ||
| 728 | hash.add_from_results facet, search(*(args + [options])) | ||
| 729 | end | ||
| 730 | |||
| 731 | hash | ||
| 732 | end | ||
| 733 | end | ||
| 734 | |||
| 735 | def facets_for_all_models(args, options) | ||
| 736 | options = GlobalFacetOptions.merge(options) | ||
| 737 | hash = ThinkingSphinx::FacetCollection.new args + [options] | ||
| 738 | options = options.merge! :group_function => :attr | ||
| 739 | |||
| 740 | facet_names(options).inject(hash) do |hash, name| | ||
| 741 | options[:group_by] = name | ||
| 742 | hash.add_from_results name, search(*(args + [options])) | ||
| 743 | hash | ||
| 744 | end | ||
| 745 | end | ||
| 746 | |||
| 747 | def facet_classes(options) | ||
| 748 | options[:classes] || ThinkingSphinx.indexed_models.collect { |model| | ||
| 749 | model.constantize | ||
| 750 | } | ||
| 751 | end | ||
| 752 | |||
| 753 | def facet_names(options) | ||
| 754 | classes = facet_classes(options) | ||
| 755 | names = options[:all_attributes] ? | ||
| 756 | facet_names_for_all_classes(classes) : | ||
| 757 | facet_names_common_to_all_classes(classes) | ||
| 758 | |||
| 759 | names.delete "class_crc" unless options[:class_facet] | ||
| 760 | names | ||
| 761 | end | ||
| 762 | |||
| 763 | def facet_names_for_all_classes(classes) | ||
| 764 | classes.collect { |klass| | ||
| 765 | klass.sphinx_facets.collect { |facet| facet.attribute_name } | ||
| 766 | }.flatten.uniq | ||
| 767 | end | ||
| 768 | |||
| 769 | def facet_names_common_to_all_classes(classes) | ||
| 770 | facet_names_for_all_classes(classes).select { |name| | ||
| 771 | classes.all? { |klass| | ||
| 772 | klass.sphinx_facets.detect { |facet| | ||
| 773 | facet.attribute_name == name | ||
| 774 | } | ||
| 775 | } | ||
| 776 | } | ||
| 777 | end | ||
| 778 | end | ||
| 779 | end | ||
| 780 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/tasks.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/tasks.rb new file mode 100644 index 0000000..ab8990e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/tasks.rb | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | require 'fileutils' | ||
| 2 | |||
| 3 | namespace :thinking_sphinx do | ||
| 4 | task :app_env do | ||
| 5 | Rake::Task[:environment].invoke if defined?(RAILS_ROOT) | ||
| 6 | Rake::Task[:merb_env].invoke if defined?(Merb) | ||
| 7 | end | ||
| 8 | |||
| 9 | desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings" | ||
| 10 | task :running_start => :app_env do | ||
| 11 | Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running? | ||
| 12 | Rake::Task["thinking_sphinx:start"].invoke | ||
| 13 | end | ||
| 14 | |||
| 15 | desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings" | ||
| 16 | task :start => :app_env do | ||
| 17 | config = ThinkingSphinx::Configuration.instance | ||
| 18 | |||
| 19 | FileUtils.mkdir_p config.searchd_file_path | ||
| 20 | raise RuntimeError, "searchd is already running." if sphinx_running? | ||
| 21 | |||
| 22 | Dir["#{config.searchd_file_path}/*.spl"].each { |file| File.delete(file) } | ||
| 23 | |||
| 24 | cmd = "#{config.bin_path}searchd --pidfile --config #{config.config_file}" | ||
| 25 | puts cmd | ||
| 26 | system cmd | ||
| 27 | |||
| 28 | sleep(2) | ||
| 29 | |||
| 30 | if sphinx_running? | ||
| 31 | puts "Started successfully (pid #{sphinx_pid})." | ||
| 32 | else | ||
| 33 | puts "Failed to start searchd daemon. Check #{config.searchd_log_file}." | ||
| 34 | end | ||
| 35 | end | ||
| 36 | |||
| 37 | desc "Stop Sphinx using Thinking Sphinx's settings" | ||
| 38 | task :stop => :app_env do | ||
| 39 | raise RuntimeError, "searchd is not running." unless sphinx_running? | ||
| 40 | config = ThinkingSphinx::Configuration.instance | ||
| 41 | pid = sphinx_pid | ||
| 42 | system "#{config.bin_path}searchd --stop --config #{config.config_file}" | ||
| 43 | puts "Stopped search daemon (pid #{pid})." | ||
| 44 | end | ||
| 45 | |||
| 46 | desc "Restart Sphinx" | ||
| 47 | task :restart => [:app_env, :stop, :start] | ||
| 48 | |||
| 49 | desc "Generate the Sphinx configuration file using Thinking Sphinx's settings" | ||
| 50 | task :configure => :app_env do | ||
| 51 | config = ThinkingSphinx::Configuration.instance | ||
| 52 | puts "Generating Configuration to #{config.config_file}" | ||
| 53 | config.build | ||
| 54 | end | ||
| 55 | |||
| 56 | desc "Index data for Sphinx using Thinking Sphinx's settings" | ||
| 57 | task :index => :app_env do | ||
| 58 | ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs | ||
| 59 | |||
| 60 | config = ThinkingSphinx::Configuration.instance | ||
| 61 | unless ENV["INDEX_ONLY"] == "true" | ||
| 62 | puts "Generating Configuration to #{config.config_file}" | ||
| 63 | config.build | ||
| 64 | end | ||
| 65 | |||
| 66 | FileUtils.mkdir_p config.searchd_file_path | ||
| 67 | cmd = "#{config.bin_path}indexer --config #{config.config_file} --all" | ||
| 68 | cmd << " --rotate" if sphinx_running? | ||
| 69 | puts cmd | ||
| 70 | system cmd | ||
| 71 | end | ||
| 72 | |||
| 73 | namespace :index do | ||
| 74 | task :delta => :app_env do | ||
| 75 | ThinkingSphinx.indexed_models.select { |model| | ||
| 76 | model.constantize.sphinx_indexes.any? { |index| index.delta? } | ||
| 77 | }.each do |model| | ||
| 78 | model.constantize.sphinx_indexes.select { |index| | ||
| 79 | index.delta? && index.delta_object.respond_to?(:delayed_index) | ||
| 80 | }.each { |index| | ||
| 81 | index.delta_object.delayed_index(index.model) | ||
| 82 | } | ||
| 83 | end | ||
| 84 | end | ||
| 85 | end | ||
| 86 | |||
| 87 | desc "Process stored delta index requests" | ||
| 88 | task :delayed_delta => :app_env do | ||
| 89 | require 'delayed/worker' | ||
| 90 | |||
| 91 | Delayed::Worker.new( | ||
| 92 | :min_priority => ENV['MIN_PRIORITY'], | ||
| 93 | :max_priority => ENV['MAX_PRIORITY'] | ||
| 94 | ).start | ||
| 95 | end | ||
| 96 | end | ||
| 97 | |||
| 98 | namespace :ts do | ||
| 99 | desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings" | ||
| 100 | task :run => "thinking_sphinx:running_start" | ||
| 101 | desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings" | ||
| 102 | task :start => "thinking_sphinx:start" | ||
| 103 | desc "Stop Sphinx using Thinking Sphinx's settings" | ||
| 104 | task :stop => "thinking_sphinx:stop" | ||
| 105 | desc "Index data for Sphinx using Thinking Sphinx's settings" | ||
| 106 | task :in => "thinking_sphinx:index" | ||
| 107 | namespace :in do | ||
| 108 | desc "Index Thinking Sphinx datetime delta indexes" | ||
| 109 | task :delta => "thinking_sphinx:index:delta" | ||
| 110 | end | ||
| 111 | task :index => "thinking_sphinx:index" | ||
| 112 | desc "Restart Sphinx" | ||
| 113 | task :restart => "thinking_sphinx:restart" | ||
| 114 | desc "Generate the Sphinx configuration file using Thinking Sphinx's settings" | ||
| 115 | task :conf => "thinking_sphinx:configure" | ||
| 116 | desc "Generate the Sphinx configuration file using Thinking Sphinx's settings" | ||
| 117 | task :config => "thinking_sphinx:configure" | ||
| 118 | desc "Process stored delta index requests" | ||
| 119 | task :dd => "thinking_sphinx:delayed_delta" | ||
| 120 | end | ||
| 121 | |||
| 122 | def sphinx_pid | ||
| 123 | ThinkingSphinx.sphinx_pid | ||
| 124 | end | ||
| 125 | |||
| 126 | def sphinx_running? | ||
| 127 | ThinkingSphinx.sphinx_running? | ||
| 128 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/rails/init.rb b/vendor/plugins/thinking-sphinx/rails/init.rb new file mode 100644 index 0000000..82ea0ee --- /dev/null +++ b/vendor/plugins/thinking-sphinx/rails/init.rb | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | require 'thinking_sphinx' | ||
| 2 | require 'action_controller/dispatcher' | ||
| 3 | |||
| 4 | ActionController::Dispatcher.to_prepare :thinking_sphinx do | ||
| 5 | ThinkingSphinx::Configuration.instance.load_models | ||
| 6 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/fixtures/data.sql b/vendor/plugins/thinking-sphinx/spec/fixtures/data.sql new file mode 100644 index 0000000..d5ec579 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/fixtures/data.sql | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Ellie','K','Ford','38 Mills Street','Eagle Farm Bc','QLD','4009','Ellie.K.Ford@mailinator.com','1970/1/23 00:00:00', 3, 'CricketTeam'); | ||
| 2 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Aaliyah','E','Allen','71 Murphy Street','Wyola West','WA','6407','Aaliyah.E.Allen@dodgit.com','1980/3/23 00:00:00', 3, 'CricketTeam'); | ||
| 3 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Callum','C','Miah','89 Dalgarno Street','Bullawa Creek','NSW','2390','Callum.C.Miah@trashymail.com','1973/3/25 00:00:00', 3, 'CricketTeam'); | ||
| 4 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Finley','L','Buckley','18 Queen Street','Manly Vale','NSW','2093','Finley.L.Buckley@spambob.com','1962/11/20 00:00:00', 3, 'CricketTeam'); | ||
| 5 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Poppy','A','Hilton','36 Nerrigundah Drive','Nyora','VIC','3987','Poppy.A.Hilton@dodgit.com','1972/10/30 00:00:00', 3, 'CricketTeam'); | ||
| 6 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Eloise','Z','Kennedy','18 Mt Berryman Road','Lilydale','QLD','4344','Eloise.Z.Kennedy@spambob.com','1973/9/28 00:00:00', 3, 'CricketTeam'); | ||
| 7 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Shannon','L','Manning','60 Ocean Pde','Greenvale','QLD','4816','Shannon.L.Manning@dodgit.com','1956/6/13 00:00:00', 3, 'CricketTeam'); | ||
| 8 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Oscar','C','Lawson','43 Feather Street','Battery Hill','QLD','4551','Oscar.C.Lawson@spambob.com','1979/10/17 00:00:00', 3, 'CricketTeam'); | ||
| 9 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Sofia','K','Bray','26 Clifton Street','Pental Island','VIC','3586','Sofia.K.Bray@mailinator.com','1970/5/10 00:00:00', 3, 'CricketTeam'); | ||
| 10 | insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Andrew','N','Byrne','35 Cecil Street','Monash Park','NSW','2111','Andrew.N.Byrne@spambob.com','1983/2/16 00:00:00', 3, 'CricketTeam'); | ||
| 11 | |||
| 12 | insert into `alphas` (name) values ('one'); | ||
| 13 | insert into `alphas` (name) values ('two'); | ||
| 14 | insert into `alphas` (name) values ('three'); | ||
| 15 | insert into `alphas` (name) values ('four'); | ||
| 16 | insert into `alphas` (name) values ('five'); | ||
| 17 | insert into `alphas` (name) values ('six'); | ||
| 18 | insert into `alphas` (name) values ('seven'); | ||
| 19 | insert into `alphas` (name) values ('eight'); | ||
| 20 | insert into `alphas` (name) values ('nine'); | ||
| 21 | insert into `alphas` (name) values ('ten'); | ||
| 22 | |||
| 23 | insert into `betas` (name) values ('one'); | ||
| 24 | insert into `betas` (name) values ('two'); | ||
| 25 | insert into `betas` (name) values ('three'); | ||
| 26 | insert into `betas` (name) values ('four'); | ||
| 27 | insert into `betas` (name) values ('five'); | ||
| 28 | insert into `betas` (name) values ('six'); | ||
| 29 | insert into `betas` (name) values ('seven'); | ||
| 30 | insert into `betas` (name) values ('eight'); | ||
| 31 | insert into `betas` (name) values ('nine'); | ||
| 32 | insert into `betas` (name) values ('ten'); | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/fixtures/database.yml.default b/vendor/plugins/thinking-sphinx/spec/fixtures/database.yml.default new file mode 100644 index 0000000..dfad2a6 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/fixtures/database.yml.default | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | username: root | ||
| 2 | password: | ||
| 3 | host: localhost \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/fixtures/models.rb b/vendor/plugins/thinking-sphinx/spec/fixtures/models.rb new file mode 100644 index 0000000..0e62906 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/fixtures/models.rb | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | class Person < ActiveRecord::Base | ||
| 2 | belongs_to :team, :polymorphic => :true | ||
| 3 | has_many :contacts | ||
| 4 | |||
| 5 | has_many :friendships | ||
| 6 | has_many :friends, :through => :friendships | ||
| 7 | |||
| 8 | has_many :tags | ||
| 9 | |||
| 10 | has_many :football_teams, :through => :tags | ||
| 11 | |||
| 12 | define_index do | ||
| 13 | indexes [first_name, middle_initial, last_name], :as => :name | ||
| 14 | indexes team.name, :as => :team_name | ||
| 15 | indexes contacts.phone_number, :as => :phone_numbers | ||
| 16 | indexes city, :prefixes => true | ||
| 17 | indexes state, :infixes => true | ||
| 18 | |||
| 19 | has [first_name, middle_initial, last_name], :as => :name_sort | ||
| 20 | has team.name, :as => :team_name_sort | ||
| 21 | |||
| 22 | has [:id, :team_id], :as => :ids | ||
| 23 | has team(:id), :as => :team_id | ||
| 24 | |||
| 25 | has contacts.phone_number, :as => :phone_number_sort | ||
| 26 | has contacts(:id), :as => :contact_ids | ||
| 27 | |||
| 28 | has birthday | ||
| 29 | |||
| 30 | has friendships.person_id, :as => :friendly_ids | ||
| 31 | |||
| 32 | set_property :delta => true | ||
| 33 | end | ||
| 34 | end | ||
| 35 | |||
| 36 | class Parent < Person | ||
| 37 | end | ||
| 38 | |||
| 39 | class Child < Person | ||
| 40 | belongs_to :parent | ||
| 41 | define_index do | ||
| 42 | indexes [parent.first_name, parent.middle_initial, parent.last_name], :as => :parent_name | ||
| 43 | end | ||
| 44 | end | ||
| 45 | |||
| 46 | class Contact < ActiveRecord::Base | ||
| 47 | belongs_to :person | ||
| 48 | end | ||
| 49 | |||
| 50 | class Tag < ActiveRecord::Base | ||
| 51 | belongs_to :person | ||
| 52 | belongs_to :football_team | ||
| 53 | belongs_to :cricket_team | ||
| 54 | end | ||
| 55 | |||
| 56 | class FootballTeam < ActiveRecord::Base | ||
| 57 | has_many :tags | ||
| 58 | end | ||
| 59 | |||
| 60 | class CricketTeam < ActiveRecord::Base | ||
| 61 | define_index do | ||
| 62 | indexes :name | ||
| 63 | has "SELECT cricket_team_id, id FROM tags", :source => :query, :as => :tags | ||
| 64 | end | ||
| 65 | end | ||
| 66 | |||
| 67 | class Friendship < ActiveRecord::Base | ||
| 68 | belongs_to :person | ||
| 69 | belongs_to :friend, :class_name => "Person", :foreign_key => :friend_id | ||
| 70 | |||
| 71 | define_index do | ||
| 72 | has person_id, friend_id | ||
| 73 | end | ||
| 74 | end | ||
| 75 | |||
| 76 | class Alpha < ActiveRecord::Base | ||
| 77 | define_index do | ||
| 78 | indexes :name, :sortable => true | ||
| 79 | |||
| 80 | set_property :field_weights => {"name" => 10} | ||
| 81 | end | ||
| 82 | end | ||
| 83 | |||
| 84 | class Beta < ActiveRecord::Base | ||
| 85 | define_index do | ||
| 86 | indexes :name, :sortable => true | ||
| 87 | |||
| 88 | set_property :delta => true | ||
| 89 | end | ||
| 90 | end | ||
| 91 | |||
| 92 | class Search < ActiveRecord::Base | ||
| 93 | # | ||
| 94 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/fixtures/structure.sql b/vendor/plugins/thinking-sphinx/spec/fixtures/structure.sql new file mode 100644 index 0000000..4ab390d --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/fixtures/structure.sql | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | DROP TABLE IF EXISTS `people`; | ||
| 2 | |||
| 3 | CREATE TABLE `people` ( | ||
| 4 | `id` int(11) NOT NULL auto_increment, | ||
| 5 | `first_name` varchar(50) NULL, | ||
| 6 | `middle_initial` varchar(10) NULL, | ||
| 7 | `last_name` varchar(50) NULL, | ||
| 8 | `gender` varchar(10) NULL, | ||
| 9 | `street_address` varchar(200) NULL, | ||
| 10 | `city` varchar(100) NULL, | ||
| 11 | `state` varchar(100) NULL, | ||
| 12 | `postcode` varchar(10) NULL, | ||
| 13 | `email` varchar(100) NULL, | ||
| 14 | `birthday` datetime NULL, | ||
| 15 | `team_id` int(11) NULL, | ||
| 16 | `team_type` varchar(50) NULL, | ||
| 17 | `type` varchar(50) NULL, | ||
| 18 | `parent_id` varchar(50) NULL, | ||
| 19 | `delta` tinyint(1) NOT NULL DEFAULT 0, | ||
| 20 | PRIMARY KEY (`id`) | ||
| 21 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 22 | |||
| 23 | DROP TABLE IF EXISTS `friendships`; | ||
| 24 | |||
| 25 | CREATE TABLE `friendships` ( | ||
| 26 | `id` int(11) NOT NULL auto_increment, | ||
| 27 | `person_id` int(11) NOT NULL, | ||
| 28 | `friend_id` int(11) NOT NULL, | ||
| 29 | `created_at` datetime NOT NULL, | ||
| 30 | `updated_at` datetime NOT NULL, | ||
| 31 | PRIMARY KEY (`id`) | ||
| 32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 33 | |||
| 34 | DROP TABLE IF EXISTS `football_teams`; | ||
| 35 | |||
| 36 | CREATE TABLE `football_teams` ( | ||
| 37 | `id` int(11) NOT NULL auto_increment, | ||
| 38 | `name` varchar(50) NOT NULL, | ||
| 39 | `state` varchar(50) NOT NULL, | ||
| 40 | PRIMARY KEY (`id`) | ||
| 41 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 42 | |||
| 43 | DROP TABLE IF EXISTS `cricket_teams`; | ||
| 44 | |||
| 45 | CREATE TABLE `cricket_teams` ( | ||
| 46 | `id` int(11) NOT NULL auto_increment, | ||
| 47 | `name` varchar(50) NOT NULL, | ||
| 48 | `state` varchar(50) NOT NULL, | ||
| 49 | PRIMARY KEY (`id`) | ||
| 50 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 51 | |||
| 52 | DROP TABLE IF EXISTS `contacts`; | ||
| 53 | |||
| 54 | CREATE TABLE `contacts` ( | ||
| 55 | `id` int(11) NOT NULL auto_increment, | ||
| 56 | `phone_number` varchar(50) NOT NULL, | ||
| 57 | `person_id` int(11) NOT NULL, | ||
| 58 | PRIMARY KEY (`id`) | ||
| 59 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 60 | |||
| 61 | DROP TABLE IF EXISTS `alphas`; | ||
| 62 | |||
| 63 | CREATE TABLE `alphas` ( | ||
| 64 | `id` int(11) NOT NULL auto_increment, | ||
| 65 | `name` varchar(50) NOT NULL, | ||
| 66 | PRIMARY KEY (`id`) | ||
| 67 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 68 | |||
| 69 | DROP TABLE IF EXISTS `betas`; | ||
| 70 | |||
| 71 | CREATE TABLE `betas` ( | ||
| 72 | `id` int(11) NOT NULL auto_increment, | ||
| 73 | `name` varchar(50) NOT NULL, | ||
| 74 | `delta` tinyint(1) NOT NULL DEFAULT 0, | ||
| 75 | PRIMARY KEY (`id`) | ||
| 76 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 77 | |||
| 78 | DROP TABLE IF EXISTS `searches`; | ||
| 79 | |||
| 80 | CREATE TABLE `searches` ( | ||
| 81 | `id` int(11) NOT NULL auto_increment, | ||
| 82 | `name` varchar(50) NOT NULL, | ||
| 83 | PRIMARY KEY (`id`) | ||
| 84 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
| 85 | |||
| 86 | DROP TABLE IF EXISTS `tags`; | ||
| 87 | |||
| 88 | CREATE TABLE `tags` ( | ||
| 89 | `id` int(11) NOT NULL auto_increment, | ||
| 90 | `person_id` int(11) NOT NULL, | ||
| 91 | `football_team_id` int(11) NOT NULL, | ||
| 92 | `cricket_team_id` int(11) NOT NULL, | ||
| 93 | `name` varchar(50) NOT NULL, | ||
| 94 | PRIMARY KEY (`id`) | ||
| 95 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/spec_helper.rb b/vendor/plugins/thinking-sphinx/spec/spec_helper.rb new file mode 100644 index 0000000..6ebce6d --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/spec_helper.rb | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | $:.unshift File.dirname(__FILE__) + '/../lib' | ||
| 2 | |||
| 3 | require 'rubygems' | ||
| 4 | require 'fileutils' | ||
| 5 | require 'ginger' | ||
| 6 | |||
| 7 | require 'lib/thinking_sphinx' | ||
| 8 | |||
| 9 | require 'not_a_mock' | ||
| 10 | require 'will_paginate' | ||
| 11 | |||
| 12 | require 'spec/sphinx_helper' | ||
| 13 | |||
| 14 | ActiveRecord::Base.logger = Logger.new(StringIO.new) | ||
| 15 | |||
| 16 | Spec::Runner.configure do |config| | ||
| 17 | %w( tmp tmp/config tmp/log tmp/db ).each do |path| | ||
| 18 | FileUtils.mkdir_p "#{Dir.pwd}/#{path}" | ||
| 19 | end | ||
| 20 | |||
| 21 | Kernel.const_set :RAILS_ROOT, "#{Dir.pwd}/tmp" unless defined?(RAILS_ROOT) | ||
| 22 | |||
| 23 | sphinx = SphinxHelper.new | ||
| 24 | sphinx.setup_mysql | ||
| 25 | |||
| 26 | require 'spec/fixtures/models' | ||
| 27 | |||
| 28 | config.before :all do | ||
| 29 | %w( tmp tmp/config tmp/log tmp/db ).each do |path| | ||
| 30 | FileUtils.mkdir_p "#{Dir.pwd}/#{path}" | ||
| 31 | end | ||
| 32 | |||
| 33 | ThinkingSphinx.updates_enabled = true | ||
| 34 | ThinkingSphinx.deltas_enabled = true | ||
| 35 | ThinkingSphinx.suppress_delta_output = true | ||
| 36 | |||
| 37 | ThinkingSphinx::Configuration.instance.reset | ||
| 38 | ThinkingSphinx::Configuration.instance.database_yml_file = "spec/fixtures/sphinx/database.yml" | ||
| 39 | |||
| 40 | # Ensure after_commit plugin is loaded correctly | ||
| 41 | Object.subclasses_of(ActiveRecord::ConnectionAdapters::AbstractAdapter).each { |klass| | ||
| 42 | unless klass.ancestors.include?(AfterCommit::ConnectionAdapters) | ||
| 43 | klass.send(:include, AfterCommit::ConnectionAdapters) | ||
| 44 | end | ||
| 45 | } | ||
| 46 | end | ||
| 47 | |||
| 48 | config.after :each do | ||
| 49 | NotAMock::CallRecorder.instance.reset | ||
| 50 | NotAMock::Stubber.instance.reset | ||
| 51 | end | ||
| 52 | |||
| 53 | config.after :all do | ||
| 54 | FileUtils.rm_r "#{Dir.pwd}/tmp" rescue nil | ||
| 55 | end | ||
| 56 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/sphinx_helper.rb b/vendor/plugins/thinking-sphinx/spec/sphinx_helper.rb new file mode 100644 index 0000000..4e67523 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/sphinx_helper.rb | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | require 'active_record' | ||
| 2 | prefix = defined?(JRUBY_VERSION) ? "jdbc" : "" | ||
| 3 | require "active_record/connection_adapters/#{prefix}mysql_adapter" | ||
| 4 | begin | ||
| 5 | require "active_record/connection_adapters/#{prefix}postgresql_adapter" | ||
| 6 | rescue LoadError | ||
| 7 | # No postgres? no prob... | ||
| 8 | end | ||
| 9 | require 'yaml' | ||
| 10 | |||
| 11 | class SphinxHelper | ||
| 12 | attr_accessor :host, :username, :password | ||
| 13 | attr_reader :path | ||
| 14 | |||
| 15 | def initialize | ||
| 16 | @host = "localhost" | ||
| 17 | @username = "thinking_sphinx" | ||
| 18 | @password = "" | ||
| 19 | |||
| 20 | if File.exist?("spec/fixtures/database.yml") | ||
| 21 | config = YAML.load(File.open("spec/fixtures/database.yml")) | ||
| 22 | @host = config["host"] | ||
| 23 | @username = config["username"] | ||
| 24 | @password = config["password"] | ||
| 25 | end | ||
| 26 | |||
| 27 | @path = File.expand_path(File.dirname(__FILE__)) | ||
| 28 | end | ||
| 29 | |||
| 30 | def mysql_adapter | ||
| 31 | defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql' | ||
| 32 | end | ||
| 33 | |||
| 34 | def setup_mysql | ||
| 35 | ActiveRecord::Base.establish_connection( | ||
| 36 | :adapter => mysql_adapter, | ||
| 37 | :database => 'thinking_sphinx', | ||
| 38 | :username => @username, | ||
| 39 | :password => @password, | ||
| 40 | :host => @host | ||
| 41 | ) | ||
| 42 | ActiveRecord::Base.logger = Logger.new(File.open("tmp/activerecord.log", "a")) | ||
| 43 | |||
| 44 | structure = File.open("spec/fixtures/structure.sql") { |f| f.read.chomp } | ||
| 45 | structure.split(';').each { |table| | ||
| 46 | ActiveRecord::Base.connection.execute table | ||
| 47 | } | ||
| 48 | |||
| 49 | File.open("spec/fixtures/data.sql") { |f| | ||
| 50 | while line = f.gets | ||
| 51 | ActiveRecord::Base.connection.execute line unless line.blank? | ||
| 52 | end | ||
| 53 | } | ||
| 54 | end | ||
| 55 | |||
| 56 | def setup_sphinx | ||
| 57 | @configuration = ThinkingSphinx::Configuration.instance.reset | ||
| 58 | File.open("spec/fixtures/sphinx/database.yml", "w") do |file| | ||
| 59 | YAML.dump({@configuration.environment => { | ||
| 60 | :adapter => mysql_adapter, | ||
| 61 | :host => @host, | ||
| 62 | :database => "thinking_sphinx", | ||
| 63 | :username => @username, | ||
| 64 | :password => @password | ||
| 65 | }}, file) | ||
| 66 | end | ||
| 67 | FileUtils.mkdir_p(@configuration.searchd_file_path) | ||
| 68 | |||
| 69 | @configuration.database_yml_file = "spec/fixtures/sphinx/database.yml" | ||
| 70 | @configuration.build | ||
| 71 | |||
| 72 | index | ||
| 73 | end | ||
| 74 | |||
| 75 | def reset | ||
| 76 | setup_mysql | ||
| 77 | end | ||
| 78 | |||
| 79 | def index | ||
| 80 | cmd = "indexer --config #{@configuration.config_file} --all" | ||
| 81 | cmd << " --rotate" if running? | ||
| 82 | `#{cmd}` | ||
| 83 | end | ||
| 84 | |||
| 85 | def start | ||
| 86 | return if running? | ||
| 87 | |||
| 88 | cmd = "searchd --config #{@configuration.config_file}" | ||
| 89 | `#{cmd}` | ||
| 90 | |||
| 91 | sleep(1) | ||
| 92 | |||
| 93 | unless running? | ||
| 94 | puts "Failed to start searchd daemon. Check #{@configuration.searchd_log_file}." | ||
| 95 | end | ||
| 96 | end | ||
| 97 | |||
| 98 | def stop | ||
| 99 | return unless running? | ||
| 100 | `kill #{pid}` | ||
| 101 | end | ||
| 102 | |||
| 103 | def pid | ||
| 104 | if File.exists?("#{@configuration.pid_file}") | ||
| 105 | `cat #{@configuration.pid_file}`[/\d+/] | ||
| 106 | else | ||
| 107 | nil | ||
| 108 | end | ||
| 109 | end | ||
| 110 | |||
| 111 | def running? | ||
| 112 | pid && `ps #{pid} | wc -l`.to_i > 1 | ||
| 113 | end | ||
| 114 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/delta_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/delta_spec.rb new file mode 100644 index 0000000..b29065f --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/delta_spec.rb | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe "ThinkingSphinx::ActiveRecord::Delta" do | ||
| 4 | it "should call the toggle_delta method after a save" do | ||
| 5 | @beta = Beta.new(:name => 'beta') | ||
| 6 | @beta.stub_method(:toggle_delta => true) | ||
| 7 | |||
| 8 | @beta.save | ||
| 9 | |||
| 10 | @beta.should have_received(:toggle_delta) | ||
| 11 | end | ||
| 12 | |||
| 13 | it "should call the toggle_delta method after a save!" do | ||
| 14 | @beta = Beta.new(:name => 'beta') | ||
| 15 | @beta.stub_method(:toggle_delta => true) | ||
| 16 | |||
| 17 | @beta.save! | ||
| 18 | |||
| 19 | @beta.should have_received(:toggle_delta) | ||
| 20 | end | ||
| 21 | |||
| 22 | describe "suspended_delta method" do | ||
| 23 | before :each do | ||
| 24 | ThinkingSphinx.stub_method(:deltas_enabled? => true) | ||
| 25 | Person.sphinx_indexes.first.delta_object.stub_method(:` => "") | ||
| 26 | end | ||
| 27 | |||
| 28 | it "should execute the argument block with deltas disabled" do | ||
| 29 | ThinkingSphinx.should_receive(:deltas_enabled=).once.with(false) | ||
| 30 | ThinkingSphinx.should_receive(:deltas_enabled=).once.with(true) | ||
| 31 | lambda { Person.suspended_delta { raise 'i was called' } }.should( | ||
| 32 | raise_error(Exception) | ||
| 33 | ) | ||
| 34 | end | ||
| 35 | |||
| 36 | it "should restore deltas_enabled to its original setting" do | ||
| 37 | ThinkingSphinx.stub_method(:deltas_enabled? => false) | ||
| 38 | ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false) | ||
| 39 | Person.suspended_delta { 'no-op' } | ||
| 40 | end | ||
| 41 | |||
| 42 | it "should restore deltas_enabled to its original setting even if there was an exception" do | ||
| 43 | ThinkingSphinx.stub_method(:deltas_enabled? => false) | ||
| 44 | ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false) | ||
| 45 | lambda { Person.suspended_delta { raise 'bad error' } }.should( | ||
| 46 | raise_error(Exception) | ||
| 47 | ) | ||
| 48 | end | ||
| 49 | |||
| 50 | it "should reindex by default after the code block is run" do | ||
| 51 | Person.should_receive(:index_delta) | ||
| 52 | Person.suspended_delta { 'no-op' } | ||
| 53 | end | ||
| 54 | |||
| 55 | it "should not reindex after the code block if false is passed in" do | ||
| 56 | Person.should_not_receive(:index_delta) | ||
| 57 | Person.suspended_delta(false) { 'no-op' } | ||
| 58 | end | ||
| 59 | end | ||
| 60 | |||
| 61 | describe "toggle_delta method" do | ||
| 62 | it "should set the delta value to true" do | ||
| 63 | @person = Person.new | ||
| 64 | |||
| 65 | @person.delta.should be_false | ||
| 66 | @person.send(:toggle_delta) | ||
| 67 | @person.delta.should be_true | ||
| 68 | end | ||
| 69 | end | ||
| 70 | |||
| 71 | describe "index_delta method" do | ||
| 72 | before :each do | ||
| 73 | ThinkingSphinx::Configuration.stub_method(:environment => "spec") | ||
| 74 | ThinkingSphinx.stub_method(:deltas_enabled? => true, :sphinx_running? => true) | ||
| 75 | Person.delta_object.stub_methods(:` => "", :toggled => true) | ||
| 76 | |||
| 77 | @person = Person.new | ||
| 78 | @person.stub_method( | ||
| 79 | :in_both_indexes? => false, | ||
| 80 | :sphinx_document_id => 1 | ||
| 81 | ) | ||
| 82 | |||
| 83 | @client = Riddle::Client.stub_instance(:update => true) | ||
| 84 | Riddle::Client.stub_method(:new => @client) | ||
| 85 | end | ||
| 86 | |||
| 87 | it "shouldn't index if delta indexing is disabled" do | ||
| 88 | ThinkingSphinx.stub_method(:deltas_enabled? => false) | ||
| 89 | |||
| 90 | @person.send(:index_delta) | ||
| 91 | |||
| 92 | Person.sphinx_indexes.first.delta_object.should_not have_received(:`) | ||
| 93 | @client.should_not have_received(:update) | ||
| 94 | end | ||
| 95 | |||
| 96 | it "shouldn't index if index updating is disabled" do | ||
| 97 | ThinkingSphinx.stub_method(:updates_enabled? => false) | ||
| 98 | |||
| 99 | @person.send(:index_delta) | ||
| 100 | |||
| 101 | Person.sphinx_indexes.first.delta_object.should_not have_received(:`) | ||
| 102 | end | ||
| 103 | |||
| 104 | it "shouldn't index if the environment is 'test'" do | ||
| 105 | ThinkingSphinx.unstub_method(:deltas_enabled?) | ||
| 106 | ThinkingSphinx.deltas_enabled = nil | ||
| 107 | ThinkingSphinx::Configuration.stub_method(:environment => "test") | ||
| 108 | |||
| 109 | @person.send(:index_delta) | ||
| 110 | |||
| 111 | Person.sphinx_indexes.first.delta_object.should_not have_received(:`) | ||
| 112 | end | ||
| 113 | |||
| 114 | it "should call indexer for the delta index" do | ||
| 115 | @person.send(:index_delta) | ||
| 116 | |||
| 117 | Person.sphinx_indexes.first.delta_object.should have_received(:`).with( | ||
| 118 | "#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config #{ThinkingSphinx::Configuration.instance.config_file} --rotate person_delta" | ||
| 119 | ) | ||
| 120 | end | ||
| 121 | |||
| 122 | it "shouldn't update the deleted attribute if not in the index" do | ||
| 123 | @person.send(:index_delta) | ||
| 124 | |||
| 125 | @client.should_not have_received(:update) | ||
| 126 | end | ||
| 127 | |||
| 128 | it "should update the deleted attribute if in the core index" do | ||
| 129 | @person.stub_method(:in_both_indexes? => true) | ||
| 130 | |||
| 131 | @person.send(:index_delta) | ||
| 132 | |||
| 133 | @client.should have_received(:update) | ||
| 134 | end | ||
| 135 | end | ||
| 136 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb new file mode 100644 index 0000000..b37ac9f --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do | ||
| 4 | describe "search method" do | ||
| 5 | before :each do | ||
| 6 | Friendship.stub_method(:search => true) | ||
| 7 | |||
| 8 | @person = Person.find(:first) | ||
| 9 | @index = Friendship.sphinx_indexes.first | ||
| 10 | end | ||
| 11 | |||
| 12 | it "should raise an error if the required attribute doesn't exist" do | ||
| 13 | @index.stub_method(:attributes => []) | ||
| 14 | |||
| 15 | lambda { @person.friendships.search "test" }.should raise_error(RuntimeError) | ||
| 16 | |||
| 17 | @index.unstub_method(:attributes) | ||
| 18 | end | ||
| 19 | |||
| 20 | it "should add a filter for the attribute into a normal search call" do | ||
| 21 | @person.friendships.search "test" | ||
| 22 | |||
| 23 | Friendship.should have_received(:search).with( | ||
| 24 | "test", :with => {:person_id => @person.id} | ||
| 25 | ) | ||
| 26 | end | ||
| 27 | end | ||
| 28 | |||
| 29 | describe "search method for has_many :through" do | ||
| 30 | before :each do | ||
| 31 | Person.stub_method(:search => true) | ||
| 32 | |||
| 33 | @person = Person.find(:first) | ||
| 34 | @index = Person.sphinx_indexes.first | ||
| 35 | end | ||
| 36 | |||
| 37 | it "should raise an error if the required attribute doesn't exist" do | ||
| 38 | @index.stub_method(:attributes => []) | ||
| 39 | |||
| 40 | lambda { @person.friends.search "test" }.should raise_error(RuntimeError) | ||
| 41 | |||
| 42 | @index.unstub_method(:attributes) | ||
| 43 | end | ||
| 44 | |||
| 45 | it "should add a filter for the attribute into a normal search call" do | ||
| 46 | @person.friends.search "test" | ||
| 47 | |||
| 48 | Person.should have_received(:search).with( | ||
| 49 | "test", :with => {:friendly_ids => @person.id} | ||
| 50 | ) | ||
| 51 | end | ||
| 52 | end | ||
| 53 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/search_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/search_spec.rb new file mode 100644 index 0000000..49c59e1 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record/search_spec.rb | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe "ThinkingSphinx::ActiveRecord::Search" do | ||
| 4 | it "should add search_for_ids to ActiveRecord::Base" do | ||
| 5 | ActiveRecord::Base.methods.should include("search_for_ids") | ||
| 6 | end | ||
| 7 | |||
| 8 | it "should add search_for_ids to ActiveRecord::Base" do | ||
| 9 | ActiveRecord::Base.methods.should include("search") | ||
| 10 | end | ||
| 11 | |||
| 12 | it "should add search_count to ActiveRecord::Base" do | ||
| 13 | ActiveRecord::Base.methods.should include("search_count") | ||
| 14 | end | ||
| 15 | |||
| 16 | it "should add search_for_id to ActiveRecord::Base" do | ||
| 17 | ActiveRecord::Base.methods.should include("search_for_id") | ||
| 18 | end | ||
| 19 | |||
| 20 | describe "search_for_ids method" do | ||
| 21 | before :each do | ||
| 22 | ThinkingSphinx::Search.stub_method(:search_for_ids => true) | ||
| 23 | end | ||
| 24 | |||
| 25 | it "should call ThinkingSphinx::Search#search_for_ids with the class option set" do | ||
| 26 | Person.search_for_ids("search") | ||
| 27 | |||
| 28 | ThinkingSphinx::Search.should have_received(:search_for_ids).with( | ||
| 29 | "search", :class => Person | ||
| 30 | ) | ||
| 31 | end | ||
| 32 | |||
| 33 | it "should override the class option" do | ||
| 34 | Person.search_for_ids("search", :class => Friendship) | ||
| 35 | |||
| 36 | ThinkingSphinx::Search.should have_received(:search_for_ids).with( | ||
| 37 | "search", :class => Person | ||
| 38 | ) | ||
| 39 | end | ||
| 40 | end | ||
| 41 | |||
| 42 | describe "search method" do | ||
| 43 | before :each do | ||
| 44 | ThinkingSphinx::Search.stub_method(:search => true) | ||
| 45 | end | ||
| 46 | |||
| 47 | it "should call ThinkingSphinx::Search#search with the class option set" do | ||
| 48 | Person.search("search") | ||
| 49 | |||
| 50 | ThinkingSphinx::Search.should have_received(:search).with( | ||
| 51 | "search", :class => Person | ||
| 52 | ) | ||
| 53 | end | ||
| 54 | |||
| 55 | it "should override the class option" do | ||
| 56 | Person.search("search", :class => Friendship) | ||
| 57 | |||
| 58 | ThinkingSphinx::Search.should have_received(:search).with( | ||
| 59 | "search", :class => Person | ||
| 60 | ) | ||
| 61 | end | ||
| 62 | end | ||
| 63 | |||
| 64 | describe "search_for_id method" do | ||
| 65 | before :each do | ||
| 66 | ThinkingSphinx::Search.stub_method(:search_for_id => true) | ||
| 67 | end | ||
| 68 | |||
| 69 | it "should call ThinkingSphinx::Search#search with the class option set" do | ||
| 70 | Person.search_for_id(10) | ||
| 71 | |||
| 72 | ThinkingSphinx::Search.should have_received(:search_for_id).with( | ||
| 73 | 10, :class => Person | ||
| 74 | ) | ||
| 75 | end | ||
| 76 | |||
| 77 | it "should override the class option" do | ||
| 78 | Person.search_for_id(10, :class => Friendship) | ||
| 79 | |||
| 80 | ThinkingSphinx::Search.should have_received(:search_for_id).with( | ||
| 81 | 10, :class => Person | ||
| 82 | ) | ||
| 83 | end | ||
| 84 | end | ||
| 85 | |||
| 86 | describe "search_count method" do | ||
| 87 | before :each do | ||
| 88 | ThinkingSphinx::Search.stub_method(:count => true) | ||
| 89 | end | ||
| 90 | |||
| 91 | it "should call ThinkingSphinx::Search#search with the class option set" do | ||
| 92 | Person.search_count("search") | ||
| 93 | |||
| 94 | ThinkingSphinx::Search.should have_received(:count).with( | ||
| 95 | "search", :class => Person | ||
| 96 | ) | ||
| 97 | end | ||
| 98 | |||
| 99 | it "should override the class option" do | ||
| 100 | Person.search_count("search", :class => Friendship) | ||
| 101 | |||
| 102 | ThinkingSphinx::Search.should have_received(:count).with( | ||
| 103 | "search", :class => Person | ||
| 104 | ) | ||
| 105 | end | ||
| 106 | end | ||
| 107 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record_spec.rb new file mode 100644 index 0000000..053d8c1 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/active_record_spec.rb | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe "ThinkingSphinx::ActiveRecord" do | ||
| 4 | describe "define_index method" do | ||
| 5 | before :each do | ||
| 6 | module TestModule | ||
| 7 | class TestModel < ActiveRecord::Base; end | ||
| 8 | end | ||
| 9 | |||
| 10 | TestModule::TestModel.stub_methods( | ||
| 11 | :before_save => true, | ||
| 12 | :after_commit => true, | ||
| 13 | :after_destroy => true | ||
| 14 | ) | ||
| 15 | |||
| 16 | @index = ThinkingSphinx::Index.stub_instance(:delta? => false) | ||
| 17 | ThinkingSphinx::Index.stub_method(:new => @index) | ||
| 18 | end | ||
| 19 | |||
| 20 | after :each do | ||
| 21 | # Remove the class so we can redefine it | ||
| 22 | TestModule.send(:remove_const, :TestModel) | ||
| 23 | |||
| 24 | ThinkingSphinx.indexed_models.delete "TestModule::TestModel" | ||
| 25 | end | ||
| 26 | |||
| 27 | it "should return nil and do nothing if indexes are disabled" do | ||
| 28 | ThinkingSphinx.stub_method(:define_indexes? => false) | ||
| 29 | |||
| 30 | TestModule::TestModel.define_index {}.should be_nil | ||
| 31 | ThinkingSphinx::Index.should_not have_received(:new) | ||
| 32 | |||
| 33 | ThinkingSphinx.unstub_method(:define_indexes?) | ||
| 34 | end | ||
| 35 | |||
| 36 | it "should add a new index to the model" do | ||
| 37 | TestModule::TestModel.define_index do; end | ||
| 38 | |||
| 39 | TestModule::TestModel.sphinx_indexes.length.should == 1 | ||
| 40 | end | ||
| 41 | |||
| 42 | it "should add to ThinkingSphinx.indexed_models if the model doesn't already exist in the array" do | ||
| 43 | TestModule::TestModel.define_index do; end | ||
| 44 | |||
| 45 | ThinkingSphinx.indexed_models.should include("TestModule::TestModel") | ||
| 46 | end | ||
| 47 | |||
| 48 | it "shouldn't add to ThinkingSphinx.indexed_models if the model already exists in the array" do | ||
| 49 | TestModule::TestModel.define_index do; end | ||
| 50 | |||
| 51 | ThinkingSphinx.indexed_models.select { |model| | ||
| 52 | model == "TestModule::TestModel" | ||
| 53 | }.length.should == 1 | ||
| 54 | |||
| 55 | TestModule::TestModel.define_index do; end | ||
| 56 | |||
| 57 | ThinkingSphinx.indexed_models.select { |model| | ||
| 58 | model == "TestModule::TestModel" | ||
| 59 | }.length.should == 1 | ||
| 60 | end | ||
| 61 | |||
| 62 | it "should add before_save and after_commit hooks to the model if delta indexing is enabled" do | ||
| 63 | @index.stub_method(:delta? => true) | ||
| 64 | |||
| 65 | TestModule::TestModel.define_index do; end | ||
| 66 | |||
| 67 | TestModule::TestModel.should have_received(:before_save) | ||
| 68 | TestModule::TestModel.should have_received(:after_commit) | ||
| 69 | end | ||
| 70 | |||
| 71 | it "should not add before_save and after_commit hooks to the model if delta indexing is disabled" do | ||
| 72 | TestModule::TestModel.define_index do; end | ||
| 73 | |||
| 74 | TestModule::TestModel.should_not have_received(:before_save) | ||
| 75 | TestModule::TestModel.should_not have_received(:after_commit) | ||
| 76 | end | ||
| 77 | |||
| 78 | it "should add an after_destroy hook with delta indexing enabled" do | ||
| 79 | @index.stub_method(:delta? => true) | ||
| 80 | |||
| 81 | TestModule::TestModel.define_index do; end | ||
| 82 | |||
| 83 | TestModule::TestModel.should have_received(:after_destroy).with(:toggle_deleted) | ||
| 84 | end | ||
| 85 | |||
| 86 | it "should add an after_destroy hook with delta indexing disabled" do | ||
| 87 | TestModule::TestModel.define_index do; end | ||
| 88 | |||
| 89 | TestModule::TestModel.should have_received(:after_destroy).with(:toggle_deleted) | ||
| 90 | end | ||
| 91 | |||
| 92 | it "should return the new index" do | ||
| 93 | TestModule::TestModel.define_index.should == @index | ||
| 94 | end | ||
| 95 | end | ||
| 96 | |||
| 97 | describe "index methods" do | ||
| 98 | before(:all) do | ||
| 99 | @person = Person.find(:first) | ||
| 100 | end | ||
| 101 | |||
| 102 | describe "in_both_indexes?" do | ||
| 103 | it "should return true if in core and delta indexes" do | ||
| 104 | @person.should_receive(:in_core_index?).and_return(true) | ||
| 105 | @person.should_receive(:in_delta_index?).and_return(true) | ||
| 106 | @person.in_both_indexes?.should be_true | ||
| 107 | end | ||
| 108 | |||
| 109 | it "should return false if in one index and not the other" do | ||
| 110 | @person.should_receive(:in_core_index?).and_return(true) | ||
| 111 | @person.should_receive(:in_delta_index?).and_return(false) | ||
| 112 | @person.in_both_indexes?.should be_false | ||
| 113 | end | ||
| 114 | end | ||
| 115 | |||
| 116 | describe "in_core_index?" do | ||
| 117 | it "should call in_index? with core" do | ||
| 118 | @person.should_receive(:in_index?).with('core') | ||
| 119 | @person.in_core_index? | ||
| 120 | end | ||
| 121 | end | ||
| 122 | |||
| 123 | describe "in_delta_index?" do | ||
| 124 | it "should call in_index? with delta" do | ||
| 125 | @person.should_receive(:in_index?).with('delta') | ||
| 126 | @person.in_delta_index? | ||
| 127 | end | ||
| 128 | end | ||
| 129 | |||
| 130 | describe "in_index?" do | ||
| 131 | it "should return true if in the specified index" do | ||
| 132 | @person.should_receive(:sphinx_document_id).and_return(1) | ||
| 133 | @person.should_receive(:sphinx_index_name).and_return('person_core') | ||
| 134 | Person.should_receive(:search_for_id).with(1, 'person_core').and_return(true) | ||
| 135 | |||
| 136 | @person.in_index?('core').should be_true | ||
| 137 | end | ||
| 138 | end | ||
| 139 | end | ||
| 140 | |||
| 141 | describe "source_of_sphinx_index method" do | ||
| 142 | it "should return self if model defines an index" do | ||
| 143 | Person.source_of_sphinx_index.should == Person | ||
| 144 | end | ||
| 145 | |||
| 146 | it "should return the parent if model inherits an index" do | ||
| 147 | Parent.source_of_sphinx_index.should == Person | ||
| 148 | end | ||
| 149 | end | ||
| 150 | |||
| 151 | describe "to_crc32 method" do | ||
| 152 | it "should return an integer" do | ||
| 153 | Person.to_crc32.should be_a_kind_of(Integer) | ||
| 154 | end | ||
| 155 | end | ||
| 156 | |||
| 157 | describe "to_crc32s method" do | ||
| 158 | it "should return an array" do | ||
| 159 | Person.to_crc32s.should be_a_kind_of(Array) | ||
| 160 | end | ||
| 161 | end | ||
| 162 | |||
| 163 | describe "toggle_deleted method" do | ||
| 164 | before :each do | ||
| 165 | ThinkingSphinx.stub_method(:sphinx_running? => true) | ||
| 166 | |||
| 167 | @configuration = ThinkingSphinx::Configuration.instance | ||
| 168 | @configuration.stub_methods( | ||
| 169 | :address => "an address", | ||
| 170 | :port => 123 | ||
| 171 | ) | ||
| 172 | @client = Riddle::Client.stub_instance(:update => true) | ||
| 173 | @person = Person.find(:first) | ||
| 174 | |||
| 175 | Riddle::Client.stub_method(:new => @client) | ||
| 176 | Person.sphinx_indexes.each { |index| index.stub_method(:delta? => false) } | ||
| 177 | @person.stub_method(:in_core_index? => true) | ||
| 178 | end | ||
| 179 | |||
| 180 | it "should create a client using the Configuration's address and port" do | ||
| 181 | @person.toggle_deleted | ||
| 182 | |||
| 183 | Riddle::Client.should have_received(:new).with( | ||
| 184 | @configuration.address, @configuration.port | ||
| 185 | ) | ||
| 186 | end | ||
| 187 | |||
| 188 | it "should update the core index's deleted flag if in core index" do | ||
| 189 | @person.toggle_deleted | ||
| 190 | |||
| 191 | @client.should have_received(:update).with( | ||
| 192 | "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => 1} | ||
| 193 | ) | ||
| 194 | end | ||
| 195 | |||
| 196 | it "shouldn't update the core index's deleted flag if the record isn't in it" do | ||
| 197 | @person.stub_method(:in_core_index? => false) | ||
| 198 | |||
| 199 | @person.toggle_deleted | ||
| 200 | |||
| 201 | @client.should_not have_received(:update).with( | ||
| 202 | "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => 1} | ||
| 203 | ) | ||
| 204 | end | ||
| 205 | |||
| 206 | it "shouldn't attempt to update the deleted flag if sphinx isn't running" do | ||
| 207 | ThinkingSphinx.stub_method(:sphinx_running? => false) | ||
| 208 | |||
| 209 | @person.toggle_deleted | ||
| 210 | |||
| 211 | @person.should_not have_received(:in_core_index?) | ||
| 212 | @client.should_not have_received(:update) | ||
| 213 | end | ||
| 214 | |||
| 215 | it "should update the delta index's deleted flag if delta indexes are enabled and the instance's delta is true" do | ||
| 216 | ThinkingSphinx.stub_method(:deltas_enabled? => true) | ||
| 217 | Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) } | ||
| 218 | @person.delta = true | ||
| 219 | |||
| 220 | @person.toggle_deleted | ||
| 221 | |||
| 222 | @client.should have_received(:update).with( | ||
| 223 | "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1} | ||
| 224 | ) | ||
| 225 | end | ||
| 226 | |||
| 227 | it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is false" do | ||
| 228 | ThinkingSphinx.stub_method(:deltas_enabled? => true) | ||
| 229 | Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) } | ||
| 230 | @person.delta = false | ||
| 231 | |||
| 232 | @person.toggle_deleted | ||
| 233 | |||
| 234 | @client.should_not have_received(:update).with( | ||
| 235 | "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1} | ||
| 236 | ) | ||
| 237 | end | ||
| 238 | |||
| 239 | it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is equivalent to false" do | ||
| 240 | ThinkingSphinx.stub_method(:deltas_enabled? => true) | ||
| 241 | Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) } | ||
| 242 | @person.delta = 0 | ||
| 243 | |||
| 244 | @person.toggle_deleted | ||
| 245 | |||
| 246 | @client.should_not have_received(:update).with( | ||
| 247 | "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1} | ||
| 248 | ) | ||
| 249 | end | ||
| 250 | |||
| 251 | it "shouldn't update the delta index if delta indexes are disabled" do | ||
| 252 | ThinkingSphinx.stub_method(:deltas_enabled? => true) | ||
| 253 | @person.toggle_deleted | ||
| 254 | |||
| 255 | @client.should_not have_received(:update).with( | ||
| 256 | "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1} | ||
| 257 | ) | ||
| 258 | end | ||
| 259 | |||
| 260 | it "should not update the delta index if delta indexing is disabled" do | ||
| 261 | ThinkingSphinx.stub_method(:deltas_enabled? => false) | ||
| 262 | Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) } | ||
| 263 | @person.delta = true | ||
| 264 | |||
| 265 | @person.toggle_deleted | ||
| 266 | |||
| 267 | @client.should_not have_received(:update).with( | ||
| 268 | "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1} | ||
| 269 | ) | ||
| 270 | end | ||
| 271 | |||
| 272 | it "should not update either index if updates are disabled" do | ||
| 273 | ThinkingSphinx.stub_methods( | ||
| 274 | :updates_enabled? => false, | ||
| 275 | :deltas_enabled => true | ||
| 276 | ) | ||
| 277 | Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) } | ||
| 278 | @person.delta = true | ||
| 279 | |||
| 280 | @person.toggle_deleted | ||
| 281 | |||
| 282 | @client.should_not have_received(:update) | ||
| 283 | end | ||
| 284 | end | ||
| 285 | |||
| 286 | describe "sphinx_indexes in the inheritance chain (STI)" do | ||
| 287 | it "should hand defined indexes on a class down to its child classes" do | ||
| 288 | Child.sphinx_indexes.should include(*Person.sphinx_indexes) | ||
| 289 | end | ||
| 290 | |||
| 291 | it "should allow associations to other STI models" do | ||
| 292 | Child.sphinx_indexes.last.link! | ||
| 293 | sql = Child.sphinx_indexes.last.to_riddle_for_core(0, 0).sql_query | ||
| 294 | sql.gsub!('$start', '0').gsub!('$end', '100') | ||
| 295 | lambda { Child.connection.execute(sql) }.should_not raise_error(ActiveRecord::StatementInvalid) | ||
| 296 | end | ||
| 297 | end | ||
| 298 | |||
| 299 | it "should return the sphinx document id as expected" do | ||
| 300 | person = Person.find(:first) | ||
| 301 | model_count = ThinkingSphinx.indexed_models.length | ||
| 302 | offset = ThinkingSphinx.indexed_models.index("Person") | ||
| 303 | |||
| 304 | (person.id * model_count + offset).should == person.sphinx_document_id | ||
| 305 | |||
| 306 | alpha = Alpha.find(:first) | ||
| 307 | offset = ThinkingSphinx.indexed_models.index("Alpha") | ||
| 308 | |||
| 309 | (alpha.id * model_count + offset).should == alpha.sphinx_document_id | ||
| 310 | |||
| 311 | beta = Beta.find(:first) | ||
| 312 | offset = ThinkingSphinx.indexed_models.index("Beta") | ||
| 313 | |||
| 314 | (beta.id * model_count + offset).should == beta.sphinx_document_id | ||
| 315 | end | ||
| 316 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/association_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/association_spec.rb new file mode 100644 index 0000000..4b92a8b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/association_spec.rb | |||
| @@ -0,0 +1,247 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Association do | ||
| 4 | describe "class-level children method" do | ||
| 5 | before :each do | ||
| 6 | @normal_reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance( | ||
| 7 | :options => {:polymorphic => false} | ||
| 8 | ) | ||
| 9 | @normal_association = ThinkingSphinx::Association.stub_instance | ||
| 10 | @poly_reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance( | ||
| 11 | :options => {:polymorphic => true}, | ||
| 12 | :macro => :has_many, | ||
| 13 | :name => "polly", | ||
| 14 | :active_record => "AR" | ||
| 15 | ) | ||
| 16 | @non_poly_reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance | ||
| 17 | |||
| 18 | Person.stub_method(:reflect_on_association => @normal_reflection) | ||
| 19 | ThinkingSphinx::Association.stub_methods( | ||
| 20 | :new => @normal_association, | ||
| 21 | :polymorphic_classes => [Person, Person], | ||
| 22 | :casted_options => {:casted => :options} | ||
| 23 | ) | ||
| 24 | ::ActiveRecord::Reflection::AssociationReflection.stub_method( | ||
| 25 | :new => @non_poly_reflection | ||
| 26 | ) | ||
| 27 | end | ||
| 28 | |||
| 29 | it "should return an empty array if no association exists" do | ||
| 30 | Person.stub_method(:reflect_on_association => nil) | ||
| 31 | |||
| 32 | ThinkingSphinx::Association.children(Person, :assoc).should == [] | ||
| 33 | end | ||
| 34 | |||
| 35 | it "should return a single association instance in an array if assocation isn't polymorphic" do | ||
| 36 | ThinkingSphinx::Association.children(Person, :assoc).should == [@normal_association] | ||
| 37 | end | ||
| 38 | |||
| 39 | it "should return multiple association instances for polymorphic associations" do | ||
| 40 | Person.stub_method(:reflect_on_association => @poly_reflection) | ||
| 41 | |||
| 42 | ThinkingSphinx::Association.children(Person, :assoc).should == | ||
| 43 | [@normal_association, @normal_association] | ||
| 44 | end | ||
| 45 | |||
| 46 | it "should generate non-polymorphic 'casted' associations for each polymorphic possibility" do | ||
| 47 | Person.stub_method(:reflect_on_association => @poly_reflection) | ||
| 48 | |||
| 49 | ThinkingSphinx::Association.children(Person, :assoc) | ||
| 50 | |||
| 51 | ThinkingSphinx::Association.should have_received(:casted_options).with( | ||
| 52 | Person, @poly_reflection | ||
| 53 | ).twice | ||
| 54 | |||
| 55 | ::ActiveRecord::Reflection::AssociationReflection.should have_received(:new).with( | ||
| 56 | :has_many, :polly_Person, {:casted => :options}, "AR" | ||
| 57 | ).twice | ||
| 58 | |||
| 59 | ThinkingSphinx::Association.should have_received(:new).with( | ||
| 60 | nil, @non_poly_reflection | ||
| 61 | ).twice | ||
| 62 | end | ||
| 63 | end | ||
| 64 | |||
| 65 | describe "instance-level children method" do | ||
| 66 | it "should return the children associations for the given association" do | ||
| 67 | @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance( | ||
| 68 | :klass => :klass | ||
| 69 | ) | ||
| 70 | @association = ThinkingSphinx::Association.new(nil, @reflection) | ||
| 71 | ThinkingSphinx::Association.stub_method(:children => :result) | ||
| 72 | |||
| 73 | @association.children(:assoc).should == :result | ||
| 74 | ThinkingSphinx::Association.should have_received(:children).with(:klass, :assoc, @association) | ||
| 75 | end | ||
| 76 | end | ||
| 77 | |||
| 78 | describe "join_to method" do | ||
| 79 | before :each do | ||
| 80 | @parent_join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance | ||
| 81 | @join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance | ||
| 82 | @parent = ThinkingSphinx::Association.stub_instance(:join_to => true, :join => nil) | ||
| 83 | @base_join = Object.stub_instance(:joins => [:a, :b, :c]) | ||
| 84 | |||
| 85 | ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_method(:new => @join) | ||
| 86 | end | ||
| 87 | |||
| 88 | it "should call the parent's join_to if parent has no join" do | ||
| 89 | @assoc = ThinkingSphinx::Association.new(@parent, :ref) | ||
| 90 | |||
| 91 | @assoc.join_to(@base_join) | ||
| 92 | |||
| 93 | @parent.should have_received(:join_to).with(@base_join) | ||
| 94 | end | ||
| 95 | |||
| 96 | it "should not call the parent's join_to if it already has a join" do | ||
| 97 | @assoc = ThinkingSphinx::Association.new(@parent, :ref) | ||
| 98 | @parent.stub_method(:join => @parent_join) | ||
| 99 | |||
| 100 | @assoc.join_to(@base_join) | ||
| 101 | |||
| 102 | @parent.should_not have_received(:join_to) | ||
| 103 | end | ||
| 104 | |||
| 105 | it "should define the join association with a JoinAssociation instance" do | ||
| 106 | @assoc = ThinkingSphinx::Association.new(@parent, :ref) | ||
| 107 | |||
| 108 | @assoc.join_to(@base_join).should == @join | ||
| 109 | @assoc.join.should == @join | ||
| 110 | end | ||
| 111 | end | ||
| 112 | |||
| 113 | describe "to_sql method" do | ||
| 114 | before :each do | ||
| 115 | @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance( | ||
| 116 | :klass => Person | ||
| 117 | ) | ||
| 118 | @association = ThinkingSphinx::Association.new(nil, @reflection) | ||
| 119 | @parent = Object.stub_instance(:aliased_table_name => "ALIAS TABLE NAME") | ||
| 120 | @join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance( | ||
| 121 | :association_join => "full association join SQL", | ||
| 122 | :parent => @parent | ||
| 123 | ) | ||
| 124 | @association.join = @join | ||
| 125 | end | ||
| 126 | |||
| 127 | it "should return the join's association join value" do | ||
| 128 | @association.to_sql.should == "full association join SQL" | ||
| 129 | end | ||
| 130 | |||
| 131 | it "should replace ::ts_join_alias:: with the aliased table name" do | ||
| 132 | @join.stub_method(:association_join => "text with ::ts_join_alias:: gone") | ||
| 133 | |||
| 134 | @association.to_sql.should == "text with `ALIAS TABLE NAME` gone" | ||
| 135 | end | ||
| 136 | end | ||
| 137 | |||
| 138 | describe "is_many? method" do | ||
| 139 | before :each do | ||
| 140 | @parent = ThinkingSphinx::Association.stub_instance( | ||
| 141 | :is_many? => :parent_is_many | ||
| 142 | ) | ||
| 143 | @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance( | ||
| 144 | :macro => :has_many | ||
| 145 | ) | ||
| 146 | end | ||
| 147 | |||
| 148 | it "should return true if association is either a has_many or a habtm" do | ||
| 149 | association = ThinkingSphinx::Association.new(@parent, @reflection) | ||
| 150 | association.is_many?.should be_true | ||
| 151 | |||
| 152 | @reflection.stub_method(:macro => :has_and_belongs_to_many) | ||
| 153 | association.is_many?.should be_true | ||
| 154 | end | ||
| 155 | |||
| 156 | it "should return the parent value if not a has many or habtm and there is a parent" do | ||
| 157 | association = ThinkingSphinx::Association.new(@parent, @reflection) | ||
| 158 | @reflection.stub_method(:macro => :belongs_to) | ||
| 159 | association.is_many?.should == :parent_is_many | ||
| 160 | end | ||
| 161 | |||
| 162 | it "should return false if no parent and not a has many or habtm" do | ||
| 163 | association = ThinkingSphinx::Association.new(nil, @reflection) | ||
| 164 | @reflection.stub_method(:macro => :belongs_to) | ||
| 165 | association.is_many?.should be_false | ||
| 166 | end | ||
| 167 | end | ||
| 168 | |||
| 169 | describe "ancestors method" do | ||
| 170 | it "should return an array of associations - including all parents" do | ||
| 171 | parent = ThinkingSphinx::Association.stub_instance(:ancestors => [:all, :ancestors]) | ||
| 172 | association = ThinkingSphinx::Association.new(parent, @reflection) | ||
| 173 | association.ancestors.should == [:all, :ancestors, association] | ||
| 174 | end | ||
| 175 | end | ||
| 176 | |||
| 177 | describe "polymorphic_classes method" do | ||
| 178 | it "should return all the polymorphic result types as classes" do | ||
| 179 | Person.connection.stub_method(:select_all => [ | ||
| 180 | {"person_type" => "Person"}, | ||
| 181 | {"person_type" => "Friendship"} | ||
| 182 | ]) | ||
| 183 | ref = Object.stub_instance( | ||
| 184 | :active_record => Person, | ||
| 185 | :options => {:foreign_type => "person_type"} | ||
| 186 | ) | ||
| 187 | |||
| 188 | ThinkingSphinx::Association.send(:polymorphic_classes, ref).should == [Person, Friendship] | ||
| 189 | end | ||
| 190 | end | ||
| 191 | |||
| 192 | describe "casted_options method" do | ||
| 193 | before :each do | ||
| 194 | @options = { | ||
| 195 | :foreign_key => "thing_id", | ||
| 196 | :foreign_type => "thing_type", | ||
| 197 | :polymorphic => true | ||
| 198 | } | ||
| 199 | @reflection = ::ActiveRecord::Reflection::AssociationReflection.stub_instance( | ||
| 200 | :options => @options | ||
| 201 | ) | ||
| 202 | end | ||
| 203 | |||
| 204 | it "should return a new options set for a specific class" do | ||
| 205 | ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == { | ||
| 206 | :polymorphic => nil, | ||
| 207 | :class_name => "Person", | ||
| 208 | :foreign_key => "thing_id", | ||
| 209 | :foreign_type => "thing_type", | ||
| 210 | :conditions => "::ts_join_alias::.`thing_type` = 'Person'" | ||
| 211 | } | ||
| 212 | end | ||
| 213 | |||
| 214 | it "should append to existing Array of conditions" do | ||
| 215 | @options[:conditions] = ["first condition"] | ||
| 216 | ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == { | ||
| 217 | :polymorphic => nil, | ||
| 218 | :class_name => "Person", | ||
| 219 | :foreign_key => "thing_id", | ||
| 220 | :foreign_type => "thing_type", | ||
| 221 | :conditions => ["first condition", "::ts_join_alias::.`thing_type` = 'Person'"] | ||
| 222 | } | ||
| 223 | end | ||
| 224 | |||
| 225 | it "should merge to an existing Hash of conditions" do | ||
| 226 | @options[:conditions] = {"field" => "value"} | ||
| 227 | ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == { | ||
| 228 | :polymorphic => nil, | ||
| 229 | :class_name => "Person", | ||
| 230 | :foreign_key => "thing_id", | ||
| 231 | :foreign_type => "thing_type", | ||
| 232 | :conditions => {"field" => "value", "thing_type" => "Person"} | ||
| 233 | } | ||
| 234 | end | ||
| 235 | |||
| 236 | it "should append to an existing String of conditions" do | ||
| 237 | @options[:conditions] = "first condition" | ||
| 238 | ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == { | ||
| 239 | :polymorphic => nil, | ||
| 240 | :class_name => "Person", | ||
| 241 | :foreign_key => "thing_id", | ||
| 242 | :foreign_type => "thing_type", | ||
| 243 | :conditions => "first condition AND ::ts_join_alias::.`thing_type` = 'Person'" | ||
| 244 | } | ||
| 245 | end | ||
| 246 | end | ||
| 247 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/attribute_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/attribute_spec.rb new file mode 100644 index 0000000..bbe1ae9 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/attribute_spec.rb | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Attribute do | ||
| 4 | describe '#initialize' do | ||
| 5 | it 'raises if no columns are provided so that configuration errors are easier to track down' do | ||
| 6 | lambda { | ||
| 7 | ThinkingSphinx::Attribute.new([]) | ||
| 8 | }.should raise_error(RuntimeError) | ||
| 9 | end | ||
| 10 | |||
| 11 | it 'raises if an element of the columns param is an integer - as happens when you use id instead of :id - so that configuration errors are easier to track down' do | ||
| 12 | lambda { | ||
| 13 | ThinkingSphinx::Attribute.new([1234]) | ||
| 14 | }.should raise_error(RuntimeError) | ||
| 15 | end | ||
| 16 | end | ||
| 17 | |||
| 18 | describe "unique_name method" do | ||
| 19 | before :each do | ||
| 20 | @attribute = ThinkingSphinx::Attribute.new [ | ||
| 21 | Object.stub_instance(:__stack => [], :__name => "col_name") | ||
| 22 | ] | ||
| 23 | end | ||
| 24 | |||
| 25 | it "should use the alias if there is one" do | ||
| 26 | @attribute.alias = "alias" | ||
| 27 | @attribute.unique_name.should == "alias" | ||
| 28 | end | ||
| 29 | |||
| 30 | it "should use the alias if there's multiple columns" do | ||
| 31 | @attribute.columns << Object.stub_instance(:__stack => [], :__name => "col_name") | ||
| 32 | @attribute.unique_name.should be_nil | ||
| 33 | |||
| 34 | @attribute.alias = "alias" | ||
| 35 | @attribute.unique_name.should == "alias" | ||
| 36 | end | ||
| 37 | |||
| 38 | it "should use the column name if there's no alias and just one column" do | ||
| 39 | @attribute.unique_name.should == "col_name" | ||
| 40 | end | ||
| 41 | end | ||
| 42 | |||
| 43 | describe "column_with_prefix method" do | ||
| 44 | before :each do | ||
| 45 | @attribute = ThinkingSphinx::Attribute.new [ | ||
| 46 | ThinkingSphinx::Index::FauxColumn.new(:col_name) | ||
| 47 | ] | ||
| 48 | @attribute.columns.each { |col| @attribute.associations[col] = [] } | ||
| 49 | @attribute.model = Person | ||
| 50 | |||
| 51 | @first_join = Object.stub_instance(:aliased_table_name => "tabular") | ||
| 52 | @second_join = Object.stub_instance(:aliased_table_name => "data") | ||
| 53 | |||
| 54 | @first_assoc = ThinkingSphinx::Association.stub_instance( | ||
| 55 | :join => @first_join, :has_column? => true | ||
| 56 | ) | ||
| 57 | @second_assoc = ThinkingSphinx::Association.stub_instance( | ||
| 58 | :join => @second_join, :has_column? => true | ||
| 59 | ) | ||
| 60 | end | ||
| 61 | |||
| 62 | it "should return the column name if the column is a string" do | ||
| 63 | @attribute.columns = [ThinkingSphinx::Index::FauxColumn.new("string")] | ||
| 64 | @attribute.send(:column_with_prefix, @attribute.columns.first).should == "string" | ||
| 65 | end | ||
| 66 | |||
| 67 | it "should return the column with model's table prefix if there's no associations for the column" do | ||
| 68 | @attribute.send(:column_with_prefix, @attribute.columns.first).should == "`people`.`col_name`" | ||
| 69 | end | ||
| 70 | |||
| 71 | it "should return the column with its join table prefix if an association exists" do | ||
| 72 | column = @attribute.columns.first | ||
| 73 | @attribute.associations[column] = [@first_assoc] | ||
| 74 | @attribute.send(:column_with_prefix, column).should == "`tabular`.`col_name`" | ||
| 75 | end | ||
| 76 | |||
| 77 | it "should return multiple columns concatenated if more than one association exists" do | ||
| 78 | column = @attribute.columns.first | ||
| 79 | @attribute.associations[column] = [@first_assoc, @second_assoc] | ||
| 80 | @attribute.send(:column_with_prefix, column).should == "`tabular`.`col_name`, `data`.`col_name`" | ||
| 81 | end | ||
| 82 | end | ||
| 83 | |||
| 84 | describe "is_many? method" do | ||
| 85 | before :each do | ||
| 86 | @assoc_a = Object.stub_instance(:is_many? => true) | ||
| 87 | @assoc_b = Object.stub_instance(:is_many? => true) | ||
| 88 | @assoc_c = Object.stub_instance(:is_many? => true) | ||
| 89 | |||
| 90 | @attribute = ThinkingSphinx::Attribute.new( | ||
| 91 | [ThinkingSphinx::Index::FauxColumn.new(:col_name)] | ||
| 92 | ) | ||
| 93 | @attribute.associations = { | ||
| 94 | :a => @assoc_a, :b => @assoc_b, :c => @assoc_c | ||
| 95 | } | ||
| 96 | end | ||
| 97 | |||
| 98 | it "should return true if all associations return true to is_many?" do | ||
| 99 | @attribute.send(:is_many?).should be_true | ||
| 100 | end | ||
| 101 | |||
| 102 | it "should return true if one association returns true to is_many?" do | ||
| 103 | @assoc_b.stub_method(:is_many? => false) | ||
| 104 | @assoc_c.stub_method(:is_many? => false) | ||
| 105 | |||
| 106 | @attribute.send(:is_many?).should be_true | ||
| 107 | end | ||
| 108 | |||
| 109 | it "should return false if all associations return false to is_many?" do | ||
| 110 | @assoc_a.stub_method(:is_many? => false) | ||
| 111 | @assoc_b.stub_method(:is_many? => false) | ||
| 112 | @assoc_c.stub_method(:is_many? => false) | ||
| 113 | |||
| 114 | @attribute.send(:is_many?).should be_false | ||
| 115 | end | ||
| 116 | end | ||
| 117 | |||
| 118 | describe "is_string? method" do | ||
| 119 | before :each do | ||
| 120 | @col_a = ThinkingSphinx::Index::FauxColumn.new("a") | ||
| 121 | @col_b = ThinkingSphinx::Index::FauxColumn.new("b") | ||
| 122 | @col_c = ThinkingSphinx::Index::FauxColumn.new("c") | ||
| 123 | |||
| 124 | @attribute = ThinkingSphinx::Attribute.new( | ||
| 125 | [@col_a, @col_b, @col_c] | ||
| 126 | ) | ||
| 127 | end | ||
| 128 | |||
| 129 | it "should return true if all columns return true to is_string?" do | ||
| 130 | @attribute.send(:is_string?).should be_true | ||
| 131 | end | ||
| 132 | |||
| 133 | it "should return false if one column returns true to is_string?" do | ||
| 134 | @col_a.send(:instance_variable_set, :@name, :a) | ||
| 135 | @attribute.send(:is_string?).should be_false | ||
| 136 | end | ||
| 137 | |||
| 138 | it "should return false if all columns return false to is_string?" do | ||
| 139 | @col_a.send(:instance_variable_set, :@name, :a) | ||
| 140 | @col_b.send(:instance_variable_set, :@name, :b) | ||
| 141 | @col_c.send(:instance_variable_set, :@name, :c) | ||
| 142 | @attribute.send(:is_string?).should be_false | ||
| 143 | end | ||
| 144 | end | ||
| 145 | |||
| 146 | describe "type method" do | ||
| 147 | before :each do | ||
| 148 | @column = ThinkingSphinx::Index::FauxColumn.new(:col_name) | ||
| 149 | @attribute = ThinkingSphinx::Attribute.new([@column]) | ||
| 150 | @attribute.model = Person | ||
| 151 | @attribute.stub_method(:is_many? => false) | ||
| 152 | end | ||
| 153 | |||
| 154 | it "should return :multi if is_many? is true" do | ||
| 155 | @attribute.stub_method(:is_many? => true) | ||
| 156 | @attribute.send(:type).should == :multi | ||
| 157 | end | ||
| 158 | |||
| 159 | it "should return :string if there's more than one association" do | ||
| 160 | @attribute.associations = {:a => [:assoc], :b => [:assoc]} | ||
| 161 | @attribute.send(:type).should == :string | ||
| 162 | end | ||
| 163 | |||
| 164 | it "should return the column type from the database if not :multi or more than one association" do | ||
| 165 | @column.send(:instance_variable_set, :@name, "birthday") | ||
| 166 | @attribute.send(:type).should == :datetime | ||
| 167 | |||
| 168 | @attribute.send(:instance_variable_set, :@type, nil) | ||
| 169 | @column.send(:instance_variable_set, :@name, "first_name") | ||
| 170 | @attribute.send(:type).should == :string | ||
| 171 | |||
| 172 | @attribute.send(:instance_variable_set, :@type, nil) | ||
| 173 | @column.send(:instance_variable_set, :@name, "id") | ||
| 174 | @attribute.send(:type).should == :integer | ||
| 175 | end | ||
| 176 | end | ||
| 177 | |||
| 178 | describe "all_ints? method" do | ||
| 179 | it "should return true if all columns are integers" do | ||
| 180 | attribute = ThinkingSphinx::Attribute.new( | ||
| 181 | [ ThinkingSphinx::Index::FauxColumn.new(:id), | ||
| 182 | ThinkingSphinx::Index::FauxColumn.new(:team_id) ] | ||
| 183 | ) | ||
| 184 | attribute.model = Person | ||
| 185 | attribute.columns.each { |col| attribute.associations[col] = [] } | ||
| 186 | |||
| 187 | attribute.send(:all_ints?).should be_true | ||
| 188 | end | ||
| 189 | |||
| 190 | it "should return false if only some columns are integers" do | ||
| 191 | attribute = ThinkingSphinx::Attribute.new( | ||
| 192 | [ ThinkingSphinx::Index::FauxColumn.new(:id), | ||
| 193 | ThinkingSphinx::Index::FauxColumn.new(:first_name) ] | ||
| 194 | ) | ||
| 195 | attribute.model = Person | ||
| 196 | attribute.columns.each { |col| attribute.associations[col] = [] } | ||
| 197 | |||
| 198 | attribute.send(:all_ints?).should be_false | ||
| 199 | end | ||
| 200 | |||
| 201 | it "should return false if no columns are integers" do | ||
| 202 | attribute = ThinkingSphinx::Attribute.new( | ||
| 203 | [ ThinkingSphinx::Index::FauxColumn.new(:first_name), | ||
| 204 | ThinkingSphinx::Index::FauxColumn.new(:last_name) ] | ||
| 205 | ) | ||
| 206 | attribute.model = Person | ||
| 207 | attribute.columns.each { |col| attribute.associations[col] = [] } | ||
| 208 | |||
| 209 | attribute.send(:all_ints?).should be_false | ||
| 210 | end | ||
| 211 | end | ||
| 212 | |||
| 213 | describe "with custom queries" do | ||
| 214 | before :each do | ||
| 215 | index = CricketTeam.sphinx_indexes.first | ||
| 216 | @statement = index.to_riddle_for_core(0, 0).sql_attr_multi.first | ||
| 217 | end | ||
| 218 | |||
| 219 | it "should track the query type accordingly" do | ||
| 220 | @statement.should match(/uint tags from query/) | ||
| 221 | end | ||
| 222 | |||
| 223 | it "should include the SQL statement" do | ||
| 224 | @statement.should match(/SELECT cricket_team_id, id FROM tags/) | ||
| 225 | end | ||
| 226 | end | ||
| 227 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/collection_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/collection_spec.rb new file mode 100644 index 0000000..b13c769 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/collection_spec.rb | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Collection do | ||
| 4 | it "should behave like WillPaginate::Collection" do | ||
| 5 | ThinkingSphinx::Collection.instance_methods.should include("previous_page") | ||
| 6 | ThinkingSphinx::Collection.instance_methods.should include("next_page") | ||
| 7 | ThinkingSphinx::Collection.instance_methods.should include("current_page") | ||
| 8 | ThinkingSphinx::Collection.instance_methods.should include("total_pages") | ||
| 9 | ThinkingSphinx::Collection.instance_methods.should include("total_entries") | ||
| 10 | ThinkingSphinx::Collection.instance_methods.should include("offset") | ||
| 11 | |||
| 12 | ThinkingSphinx::Collection.ancestors.should include(Array) | ||
| 13 | end | ||
| 14 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/configuration_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/configuration_spec.rb new file mode 100644 index 0000000..12e2775 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/configuration_spec.rb | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Configuration do | ||
| 4 | describe "environment class method" do | ||
| 5 | before :each do | ||
| 6 | ThinkingSphinx::Configuration.send(:class_variable_set, :@@environment, nil) | ||
| 7 | |||
| 8 | ENV["RAILS_ENV"] = nil | ||
| 9 | end | ||
| 10 | |||
| 11 | it "should use the Merb environment value if set" do | ||
| 12 | unless defined?(Merb) | ||
| 13 | module Merb; end | ||
| 14 | end | ||
| 15 | |||
| 16 | ThinkingSphinx::Configuration.stub_method(:defined? => true) | ||
| 17 | Merb.stub_method(:environment => "merb_production") | ||
| 18 | ThinkingSphinx::Configuration.environment.should == "merb_production" | ||
| 19 | |||
| 20 | Object.send(:remove_const, :Merb) | ||
| 21 | end | ||
| 22 | |||
| 23 | it "should use the Rails environment value if set" do | ||
| 24 | ENV["RAILS_ENV"] = "rails_production" | ||
| 25 | ThinkingSphinx::Configuration.environment.should == "rails_production" | ||
| 26 | end | ||
| 27 | |||
| 28 | it "should default to development" do | ||
| 29 | ThinkingSphinx::Configuration.environment.should == "development" | ||
| 30 | end | ||
| 31 | end | ||
| 32 | |||
| 33 | describe "parse_config method" do | ||
| 34 | before :each do | ||
| 35 | @settings = { | ||
| 36 | "development" => { | ||
| 37 | "config_file" => "tmp/config/development.sphinx.conf", | ||
| 38 | "searchd_log_file" => "searchd_log_file.log", | ||
| 39 | "query_log_file" => "query_log_file.log", | ||
| 40 | "pid_file" => "pid_file.pid", | ||
| 41 | "searchd_file_path" => "searchd/file/path", | ||
| 42 | "address" => "127.0.0.1", | ||
| 43 | "port" => 3333, | ||
| 44 | "min_prefix_len" => 2, | ||
| 45 | "min_infix_len" => 3, | ||
| 46 | "mem_limit" => "128M", | ||
| 47 | "max_matches" => 1001, | ||
| 48 | "morphology" => "stem_ru", | ||
| 49 | "charset_type" => "latin1", | ||
| 50 | "charset_table" => "table", | ||
| 51 | "ignore_chars" => "e" | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f| | ||
| 56 | f.write YAML.dump(@settings) | ||
| 57 | end | ||
| 58 | end | ||
| 59 | |||
| 60 | it "should use the accessors to set the configuration values" do | ||
| 61 | config = ThinkingSphinx::Configuration.instance | ||
| 62 | config.send(:parse_config) | ||
| 63 | |||
| 64 | %w(config_file searchd_log_file query_log_file pid_file searchd_file_path | ||
| 65 | address port).each do |key| | ||
| 66 | config.send(key).should == @settings["development"][key] | ||
| 67 | end | ||
| 68 | end | ||
| 69 | |||
| 70 | after :each do | ||
| 71 | FileUtils.rm "#{RAILS_ROOT}/config/sphinx.yml" | ||
| 72 | end | ||
| 73 | end | ||
| 74 | |||
| 75 | describe "initialisation" do | ||
| 76 | it "should have a default bin_path of nothing" do | ||
| 77 | ThinkingSphinx::Configuration.instance.bin_path.should == "" | ||
| 78 | end | ||
| 79 | |||
| 80 | it "should append a / to bin_path if one is supplied" do | ||
| 81 | @settings = { | ||
| 82 | "development" => { | ||
| 83 | "bin_path" => "path/to/somewhere" | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f| | ||
| 88 | f.write YAML.dump(@settings) | ||
| 89 | end | ||
| 90 | |||
| 91 | ThinkingSphinx::Configuration.instance.send(:parse_config) | ||
| 92 | ThinkingSphinx::Configuration.instance.bin_path.should match(/\/$/) | ||
| 93 | end | ||
| 94 | end | ||
| 95 | |||
| 96 | it "should insert set index options into the configuration file" do | ||
| 97 | config = ThinkingSphinx::Configuration.instance | ||
| 98 | ThinkingSphinx::Configuration::IndexOptions.each do |option| | ||
| 99 | config.index_options[option.to_sym] = "something" | ||
| 100 | config.build | ||
| 101 | |||
| 102 | file = open(config.config_file) { |f| f.read } | ||
| 103 | file.should match(/#{option}\s+= something/) | ||
| 104 | |||
| 105 | config.index_options[option.to_sym] = nil | ||
| 106 | end | ||
| 107 | end | ||
| 108 | |||
| 109 | it "should insert set source options into the configuration file" do | ||
| 110 | config = ThinkingSphinx::Configuration.instance | ||
| 111 | ThinkingSphinx::Configuration::SourceOptions.each do |option| | ||
| 112 | config.source_options[option.to_sym] = "something" | ||
| 113 | config.build | ||
| 114 | |||
| 115 | file = open(config.config_file) { |f| f.read } | ||
| 116 | file.should match(/#{option}\s+= something/) | ||
| 117 | |||
| 118 | config.source_options[option.to_sym] = nil | ||
| 119 | end | ||
| 120 | end | ||
| 121 | |||
| 122 | it "should set any explicit prefixed or infixed fields" do | ||
| 123 | file = open(ThinkingSphinx::Configuration.instance.config_file) { |f| | ||
| 124 | f.read | ||
| 125 | } | ||
| 126 | file.should match(/prefix_fields\s+= city/) | ||
| 127 | file.should match(/infix_fields\s+= state/) | ||
| 128 | end | ||
| 129 | |||
| 130 | it "should not have prefix fields in indexes where nothing is set" do | ||
| 131 | file = open(ThinkingSphinx::Configuration.instance.config_file) { |f| | ||
| 132 | f.read | ||
| 133 | } | ||
| 134 | file.should_not match(/index alpha_core\s+\{\s+[^\}]*prefix_fields\s+=[^\}]*\}/m) | ||
| 135 | end | ||
| 136 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/core/string_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/core/string_spec.rb new file mode 100644 index 0000000..26f813c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/core/string_spec.rb | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe String do | ||
| 4 | describe "to_crc32 instance method" do | ||
| 5 | it "should return an integer" do | ||
| 6 | 'to_crc32'.to_crc32.should be_a_kind_of(Integer) | ||
| 7 | end | ||
| 8 | end | ||
| 9 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/field_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/field_spec.rb new file mode 100644 index 0000000..770f749 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/field_spec.rb | |||
| @@ -0,0 +1,145 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Field do | ||
| 4 | describe '#initialize' do | ||
| 5 | it 'raises if no columns are provided so that configuration errors are easier to track down' do | ||
| 6 | lambda { | ||
| 7 | ThinkingSphinx::Field.new([]) | ||
| 8 | }.should raise_error(RuntimeError) | ||
| 9 | end | ||
| 10 | |||
| 11 | it 'raises if an element of the columns param is an integer - as happens when you use id instead of :id - so that configuration errors are easier to track down' do | ||
| 12 | lambda { | ||
| 13 | ThinkingSphinx::Field.new([1234]) | ||
| 14 | }.should raise_error(RuntimeError) | ||
| 15 | end | ||
| 16 | end | ||
| 17 | |||
| 18 | describe "unique_name method" do | ||
| 19 | before :each do | ||
| 20 | @field = ThinkingSphinx::Field.new [ | ||
| 21 | Object.stub_instance(:__stack => [], :__name => "col_name") | ||
| 22 | ] | ||
| 23 | end | ||
| 24 | |||
| 25 | it "should use the alias if there is one" do | ||
| 26 | @field.alias = "alias" | ||
| 27 | @field.unique_name.should == "alias" | ||
| 28 | end | ||
| 29 | |||
| 30 | it "should use the alias if there's multiple columns" do | ||
| 31 | @field.columns << Object.stub_instance(:__stack => [], :__name => "col_name") | ||
| 32 | @field.unique_name.should be_nil | ||
| 33 | |||
| 34 | @field.alias = "alias" | ||
| 35 | @field.unique_name.should == "alias" | ||
| 36 | end | ||
| 37 | |||
| 38 | it "should use the column name if there's no alias and just one column" do | ||
| 39 | @field.unique_name.should == "col_name" | ||
| 40 | end | ||
| 41 | end | ||
| 42 | |||
| 43 | describe "prefixes method" do | ||
| 44 | it "should default to false" do | ||
| 45 | @field = ThinkingSphinx::Field.new([Object.stub_instance(:__stack => [])]) | ||
| 46 | @field.prefixes.should be_false | ||
| 47 | end | ||
| 48 | |||
| 49 | it "should be true if the corresponding option is set" do | ||
| 50 | @field = ThinkingSphinx::Field.new( | ||
| 51 | [Object.stub_instance(:__stack => [])], :prefixes => true | ||
| 52 | ) | ||
| 53 | @field.prefixes.should be_true | ||
| 54 | end | ||
| 55 | end | ||
| 56 | |||
| 57 | describe "infixes method" do | ||
| 58 | it "should default to false" do | ||
| 59 | @field = ThinkingSphinx::Field.new([Object.stub_instance(:__stack => [])]) | ||
| 60 | @field.infixes.should be_false | ||
| 61 | end | ||
| 62 | |||
| 63 | it "should be true if the corresponding option is set" do | ||
| 64 | @field = ThinkingSphinx::Field.new( | ||
| 65 | [Object.stub_instance(:__stack => [])], :infixes => true | ||
| 66 | ) | ||
| 67 | @field.infixes.should be_true | ||
| 68 | end | ||
| 69 | end | ||
| 70 | |||
| 71 | describe "column_with_prefix method" do | ||
| 72 | before :each do | ||
| 73 | @field = ThinkingSphinx::Field.new [ | ||
| 74 | ThinkingSphinx::Index::FauxColumn.new(:col_name) | ||
| 75 | ] | ||
| 76 | @field.columns.each { |col| @field.associations[col] = [] } | ||
| 77 | @field.model = Person | ||
| 78 | |||
| 79 | @first_join = Object.stub_instance(:aliased_table_name => "tabular") | ||
| 80 | @second_join = Object.stub_instance(:aliased_table_name => "data") | ||
| 81 | |||
| 82 | @first_assoc = ThinkingSphinx::Association.stub_instance( | ||
| 83 | :join => @first_join, :has_column? => true | ||
| 84 | ) | ||
| 85 | @second_assoc = ThinkingSphinx::Association.stub_instance( | ||
| 86 | :join => @second_join, :has_column? => true | ||
| 87 | ) | ||
| 88 | end | ||
| 89 | |||
| 90 | it "should return the column name if the column is a string" do | ||
| 91 | @field.columns = [ThinkingSphinx::Index::FauxColumn.new("string")] | ||
| 92 | @field.send(:column_with_prefix, @field.columns.first).should == "string" | ||
| 93 | end | ||
| 94 | |||
| 95 | it "should return the column with model's table prefix if there's no associations for the column" do | ||
| 96 | @field.send(:column_with_prefix, @field.columns.first).should == "`people`.`col_name`" | ||
| 97 | end | ||
| 98 | |||
| 99 | it "should return the column with its join table prefix if an association exists" do | ||
| 100 | column = @field.columns.first | ||
| 101 | @field.associations[column] = [@first_assoc] | ||
| 102 | @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`" | ||
| 103 | end | ||
| 104 | |||
| 105 | it "should return multiple columns concatenated if more than one association exists" do | ||
| 106 | column = @field.columns.first | ||
| 107 | @field.associations[column] = [@first_assoc, @second_assoc] | ||
| 108 | @field.send(:column_with_prefix, column).should == "`tabular`.`col_name`, `data`.`col_name`" | ||
| 109 | end | ||
| 110 | end | ||
| 111 | |||
| 112 | describe "is_many? method" do | ||
| 113 | before :each do | ||
| 114 | @assoc_a = Object.stub_instance(:is_many? => true) | ||
| 115 | @assoc_b = Object.stub_instance(:is_many? => true) | ||
| 116 | @assoc_c = Object.stub_instance(:is_many? => true) | ||
| 117 | |||
| 118 | @field = ThinkingSphinx::Field.new( | ||
| 119 | [ThinkingSphinx::Index::FauxColumn.new(:col_name)] | ||
| 120 | ) | ||
| 121 | @field.associations = { | ||
| 122 | :a => @assoc_a, :b => @assoc_b, :c => @assoc_c | ||
| 123 | } | ||
| 124 | end | ||
| 125 | |||
| 126 | it "should return true if all associations return true to is_many?" do | ||
| 127 | @field.send(:is_many?).should be_true | ||
| 128 | end | ||
| 129 | |||
| 130 | it "should return true if one association returns true to is_many?" do | ||
| 131 | @assoc_b.stub_method(:is_many? => false) | ||
| 132 | @assoc_c.stub_method(:is_many? => false) | ||
| 133 | |||
| 134 | @field.send(:is_many?).should be_true | ||
| 135 | end | ||
| 136 | |||
| 137 | it "should return false if all associations return false to is_many?" do | ||
| 138 | @assoc_a.stub_method(:is_many? => false) | ||
| 139 | @assoc_b.stub_method(:is_many? => false) | ||
| 140 | @assoc_c.stub_method(:is_many? => false) | ||
| 141 | |||
| 142 | @field.send(:is_many?).should be_false | ||
| 143 | end | ||
| 144 | end | ||
| 145 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index/builder_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index/builder_spec.rb new file mode 100644 index 0000000..6d1d25d --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index/builder_spec.rb | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Index::Builder do | ||
| 4 | # | ||
| 5 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index/faux_column_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index/faux_column_spec.rb new file mode 100644 index 0000000..ca76a34 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index/faux_column_spec.rb | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Index::FauxColumn do | ||
| 4 | describe "coerce class method" do | ||
| 5 | before :each do | ||
| 6 | @column = ThinkingSphinx::Index::FauxColumn.stub_instance | ||
| 7 | ThinkingSphinx::Index::FauxColumn.stub_method(:new => @column) | ||
| 8 | end | ||
| 9 | |||
| 10 | it "should return a single faux column if passed a string" do | ||
| 11 | ThinkingSphinx::Index::FauxColumn.coerce("string").should == @column | ||
| 12 | end | ||
| 13 | |||
| 14 | it "should return a single faux column if passed a symbol" do | ||
| 15 | ThinkingSphinx::Index::FauxColumn.coerce(:string).should == @column | ||
| 16 | end | ||
| 17 | |||
| 18 | it "should return an array of faux columns if passed an array of strings" do | ||
| 19 | ThinkingSphinx::Index::FauxColumn.coerce(["one", "two"]).should == [ | ||
| 20 | @column, @column | ||
| 21 | ] | ||
| 22 | end | ||
| 23 | |||
| 24 | it "should return an array of faux columns if passed an array of symbols" do | ||
| 25 | ThinkingSphinx::Index::FauxColumn.coerce([:one, :two]).should == [ | ||
| 26 | @column, @column | ||
| 27 | ] | ||
| 28 | end | ||
| 29 | end | ||
| 30 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index_spec.rb new file mode 100644 index 0000000..fe1cba0 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/index_spec.rb | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::Index do | ||
| 4 | describe "generated sql_query" do | ||
| 5 | it "should include explicit groupings if requested" do | ||
| 6 | @index = ThinkingSphinx::Index.new(Person) | ||
| 7 | |||
| 8 | @index.groupings << "custom_sql" | ||
| 9 | @index.to_riddle_for_core(0, 0).sql_query.should match(/GROUP BY.+custom_sql/) | ||
| 10 | end | ||
| 11 | end | ||
| 12 | |||
| 13 | describe "prefix_fields method" do | ||
| 14 | before :each do | ||
| 15 | @index = ThinkingSphinx::Index.new(Person) | ||
| 16 | |||
| 17 | @field_a = ThinkingSphinx::Field.stub_instance(:prefixes => true) | ||
| 18 | @field_b = ThinkingSphinx::Field.stub_instance(:prefixes => false) | ||
| 19 | @field_c = ThinkingSphinx::Field.stub_instance(:prefixes => true) | ||
| 20 | |||
| 21 | @index.fields = [@field_a, @field_b, @field_c] | ||
| 22 | end | ||
| 23 | |||
| 24 | it "should return fields that are flagged as prefixed" do | ||
| 25 | @index.prefix_fields.should include(@field_a) | ||
| 26 | @index.prefix_fields.should include(@field_c) | ||
| 27 | end | ||
| 28 | |||
| 29 | it "should not return fields that aren't flagged as prefixed" do | ||
| 30 | @index.prefix_fields.should_not include(@field_b) | ||
| 31 | end | ||
| 32 | end | ||
| 33 | |||
| 34 | describe "infix_fields method" do | ||
| 35 | before :each do | ||
| 36 | @index = ThinkingSphinx::Index.new(Person) | ||
| 37 | |||
| 38 | @field_a = ThinkingSphinx::Field.stub_instance(:infixes => true) | ||
| 39 | @field_b = ThinkingSphinx::Field.stub_instance(:infixes => false) | ||
| 40 | @field_c = ThinkingSphinx::Field.stub_instance(:infixes => true) | ||
| 41 | |||
| 42 | @index.fields = [@field_a, @field_b, @field_c] | ||
| 43 | end | ||
| 44 | |||
| 45 | it "should return fields that are flagged as infixed" do | ||
| 46 | @index.infix_fields.should include(@field_a) | ||
| 47 | @index.infix_fields.should include(@field_c) | ||
| 48 | end | ||
| 49 | |||
| 50 | it "should not return fields that aren't flagged as infixed" do | ||
| 51 | @index.infix_fields.should_not include(@field_b) | ||
| 52 | end | ||
| 53 | end | ||
| 54 | |||
| 55 | describe "multi-value attribute as ranged-query with has-many association" do | ||
| 56 | before :each do | ||
| 57 | @index = ThinkingSphinx::Index.new(Person) do | ||
| 58 | has tags(:id), :as => :tag_ids, :source => :ranged_query | ||
| 59 | end | ||
| 60 | @index.link! | ||
| 61 | |||
| 62 | @sql = @index.to_riddle_for_core(0, 0).sql_query | ||
| 63 | end | ||
| 64 | |||
| 65 | it "should not include attribute in select-clause sql_query" do | ||
| 66 | @sql.should_not match(/tag_ids/) | ||
| 67 | @sql.should_not match(/GROUP_CONCAT\(`tags`.`id`/) | ||
| 68 | end | ||
| 69 | |||
| 70 | it "should not join with association table" do | ||
| 71 | @sql.should_not match(/LEFT OUTER JOIN `tags`/) | ||
| 72 | end | ||
| 73 | |||
| 74 | it "should include sql_attr_multi as ranged-query" do | ||
| 75 | attribute = @index.send(:attributes).first | ||
| 76 | attribute.send(:type_to_config).to_s.should == "sql_attr_multi" | ||
| 77 | |||
| 78 | declaration, query, range_query = attribute.send(:config_value).split('; ') | ||
| 79 | declaration.should == "uint tag_ids from ranged-query" | ||
| 80 | query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end" | ||
| 81 | range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`" | ||
| 82 | end | ||
| 83 | end | ||
| 84 | |||
| 85 | describe "multi-value attribute as ranged-query with has-many-through association" do | ||
| 86 | before :each do | ||
| 87 | @index = ThinkingSphinx::Index.new(Person) do | ||
| 88 | has football_teams(:id), :as => :football_teams_ids, :source => :ranged_query | ||
| 89 | end | ||
| 90 | @index.link! | ||
| 91 | |||
| 92 | @sql = @index.to_riddle_for_core(0, 0).sql_query | ||
| 93 | end | ||
| 94 | |||
| 95 | it "should not include attribute in select-clause sql_query" do | ||
| 96 | @sql.should_not match(/football_teams_ids/) | ||
| 97 | @sql.should_not match(/GROUP_CONCAT\(`tags`.`football_team_id`/) | ||
| 98 | end | ||
| 99 | |||
| 100 | it "should not join with association table" do | ||
| 101 | @sql.should_not match(/LEFT OUTER JOIN `tags`/) | ||
| 102 | end | ||
| 103 | |||
| 104 | it "should include sql_attr_multi as ranged-query" do | ||
| 105 | attribute = @index.send(:attributes).first | ||
| 106 | attribute.send(:type_to_config).to_s.should == "sql_attr_multi" | ||
| 107 | |||
| 108 | declaration, query, range_query = attribute.send(:config_value).split('; ') | ||
| 109 | declaration.should == "uint football_teams_ids from ranged-query" | ||
| 110 | query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`football_team_id` AS `football_teams_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end" | ||
| 111 | range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`" | ||
| 112 | end | ||
| 113 | end | ||
| 114 | |||
| 115 | describe "multi-value attribute as ranged-query with has-many-through association and foreign_key" do | ||
| 116 | before :each do | ||
| 117 | @index = ThinkingSphinx::Index.new(Person) do | ||
| 118 | has friends(:id), :as => :friend_ids, :source => :ranged_query | ||
| 119 | end | ||
| 120 | @index.link! | ||
| 121 | |||
| 122 | @sql = @index.to_riddle_for_core(0, 0).sql_query | ||
| 123 | end | ||
| 124 | |||
| 125 | it "should not include attribute in select-clause sql_query" do | ||
| 126 | @sql.should_not match(/friend_ids/) | ||
| 127 | @sql.should_not match(/GROUP_CONCAT\(`friendships`.`friend_id`/) | ||
| 128 | end | ||
| 129 | |||
| 130 | it "should not join with association table" do | ||
| 131 | @sql.should_not match(/LEFT OUTER JOIN `friendships`/) | ||
| 132 | end | ||
| 133 | |||
| 134 | it "should include sql_attr_multi as ranged-query" do | ||
| 135 | attribute = @index.send(:attributes).first | ||
| 136 | attribute.send(:type_to_config).to_s.should == "sql_attr_multi" | ||
| 137 | |||
| 138 | declaration, query, range_query = attribute.send(:config_value).split('; ') | ||
| 139 | declaration.should == "uint friend_ids from ranged-query" | ||
| 140 | query.should == "SELECT `friendships`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `friendships`.`friend_id` AS `friend_ids` FROM `friendships` WHERE `friendships`.`person_id` >= $start AND `friendships`.`person_id` <= $end" | ||
| 141 | range_query.should == "SELECT MIN(`friendships`.`person_id`), MAX(`friendships`.`person_id`) FROM `friendships`" | ||
| 142 | end | ||
| 143 | end | ||
| 144 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/rails_additions_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/rails_additions_spec.rb new file mode 100644 index 0000000..6453812 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/rails_additions_spec.rb | |||
| @@ -0,0 +1,183 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx::HashExcept do | ||
| 4 | before(:each) do | ||
| 5 | @hash = { :number => 20, :letter => 'b', :shape => 'rectangle' } | ||
| 6 | end | ||
| 7 | |||
| 8 | describe "except method" do | ||
| 9 | it "returns a hash without the specified keys" do | ||
| 10 | new_hash = @hash.except(:number) | ||
| 11 | new_hash.should_not have_key(:number) | ||
| 12 | end | ||
| 13 | end | ||
| 14 | |||
| 15 | describe "except! method" do | ||
| 16 | it "modifies hash removing specified keys" do | ||
| 17 | @hash.except!(:number) | ||
| 18 | @hash.should_not have_key(:number) | ||
| 19 | end | ||
| 20 | end | ||
| 21 | |||
| 22 | describe "extends Hash" do | ||
| 23 | it 'with except' do | ||
| 24 | Hash.instance_methods.include?('except').should be_true | ||
| 25 | end | ||
| 26 | |||
| 27 | it 'with except!' do | ||
| 28 | Hash.instance_methods.include?('except!').should be_true | ||
| 29 | end | ||
| 30 | end | ||
| 31 | end | ||
| 32 | |||
| 33 | describe ThinkingSphinx::ArrayExtractOptions do | ||
| 34 | describe 'extract_options! method' do | ||
| 35 | it 'returns a hash' do | ||
| 36 | array = [] | ||
| 37 | array.extract_options!.should be_kind_of(Hash) | ||
| 38 | end | ||
| 39 | |||
| 40 | it 'returns the last option if it is a hash' do | ||
| 41 | array = ['a', 'b', {:c => 'd'}] | ||
| 42 | array.extract_options!.should == {:c => 'd'} | ||
| 43 | end | ||
| 44 | end | ||
| 45 | |||
| 46 | describe "extends Array" do | ||
| 47 | it 'with extract_options!' do | ||
| 48 | Array.instance_methods.include?('extract_options!').should be_true | ||
| 49 | end | ||
| 50 | end | ||
| 51 | end | ||
| 52 | |||
| 53 | describe ThinkingSphinx::AbstractQuotedTableName do | ||
| 54 | describe 'quote_table_name method' do | ||
| 55 | it 'calls quote_column_name' do | ||
| 56 | adapter = ActiveRecord::ConnectionAdapters::AbstractAdapter.new(defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql') | ||
| 57 | adapter.should_receive(:quote_column_name).with('messages') | ||
| 58 | adapter.quote_table_name('messages') | ||
| 59 | end | ||
| 60 | end | ||
| 61 | |||
| 62 | describe "extends ActiveRecord::ConnectionAdapters::AbstractAdapter" do | ||
| 63 | it 'with quote_table_name' do | ||
| 64 | ActiveRecord::ConnectionAdapters::AbstractAdapter.instance_methods.include?('quote_table_name').should be_true | ||
| 65 | end | ||
| 66 | end | ||
| 67 | end | ||
| 68 | |||
| 69 | describe ThinkingSphinx::MysqlQuotedTableName do | ||
| 70 | describe "quote_table_name method" do | ||
| 71 | it 'correctly quotes' do | ||
| 72 | adapter = ActiveRecord::Base.connection | ||
| 73 | adapter.quote_table_name('thinking_sphinx.messages').should == "`thinking_sphinx`.`messages`" | ||
| 74 | end | ||
| 75 | end | ||
| 76 | |||
| 77 | describe "extends ActiveRecord::ConnectionAdapters::MysqlAdapter" do | ||
| 78 | it 'with quote_table_name' do | ||
| 79 | adapter = defined?(JRUBY_VERSION) ? :JdbcAdapter : :MysqlAdapter | ||
| 80 | ActiveRecord::ConnectionAdapters.const_get(adapter).instance_methods.include?("quote_table_name").should be_true | ||
| 81 | end | ||
| 82 | end | ||
| 83 | end | ||
| 84 | |||
| 85 | describe ThinkingSphinx::ActiveRecordQuotedName do | ||
| 86 | describe "quoted_table_name method" do | ||
| 87 | it 'returns table name wrappd in quotes' do | ||
| 88 | Person.quoted_table_name.should == '`people`' | ||
| 89 | end | ||
| 90 | end | ||
| 91 | |||
| 92 | describe "extends ActiveRecord::Base" do | ||
| 93 | it 'with quoted_table_name' do | ||
| 94 | ActiveRecord::Base.respond_to?("quoted_table_name").should be_true | ||
| 95 | end | ||
| 96 | end | ||
| 97 | end | ||
| 98 | |||
| 99 | describe ThinkingSphinx::ActiveRecordStoreFullSTIClass do | ||
| 100 | describe "store_full_sti_class method" do | ||
| 101 | it 'returns false' do | ||
| 102 | Person.store_full_sti_class.should be_false | ||
| 103 | end | ||
| 104 | end | ||
| 105 | |||
| 106 | describe "extends ActiveRecord::Base" do | ||
| 107 | it 'with store_full_sti_class' do | ||
| 108 | ActiveRecord::Base.respond_to?(:store_full_sti_class).should be_true | ||
| 109 | end | ||
| 110 | end | ||
| 111 | end | ||
| 112 | |||
| 113 | class TestModel | ||
| 114 | @@squares = 89 | ||
| 115 | @@circles = 43 | ||
| 116 | |||
| 117 | def number_of_polygons | ||
| 118 | @@polygons | ||
| 119 | end | ||
| 120 | end | ||
| 121 | |||
| 122 | describe ThinkingSphinx::ClassAttributeMethods do | ||
| 123 | describe "cattr_reader method" do | ||
| 124 | it 'creates getters' do | ||
| 125 | TestModel.cattr_reader :herbivores | ||
| 126 | test_model = TestModel.new | ||
| 127 | test_model.respond_to?(:herbivores).should be_true | ||
| 128 | end | ||
| 129 | |||
| 130 | it 'sets the initial value to nil' do | ||
| 131 | TestModel.cattr_reader :carnivores | ||
| 132 | test_model = TestModel.new | ||
| 133 | test_model.carnivores.should be_nil | ||
| 134 | end | ||
| 135 | |||
| 136 | it 'does not override an existing definition' do | ||
| 137 | TestModel.cattr_reader :squares | ||
| 138 | test_model = TestModel.new | ||
| 139 | test_model.squares.should == 89 | ||
| 140 | end | ||
| 141 | end | ||
| 142 | |||
| 143 | describe "cattr_writer method" do | ||
| 144 | it 'creates setters' do | ||
| 145 | TestModel.cattr_writer :herbivores | ||
| 146 | test_model = TestModel.new | ||
| 147 | test_model.respond_to?(:herbivores=).should be_true | ||
| 148 | end | ||
| 149 | |||
| 150 | it 'does not override an existing definition' do | ||
| 151 | TestModel.cattr_writer :polygons | ||
| 152 | test_model = TestModel.new | ||
| 153 | test_model.polygons = 100 | ||
| 154 | test_model.number_of_polygons.should == 100 | ||
| 155 | end | ||
| 156 | end | ||
| 157 | |||
| 158 | describe "cattr_accessor method" do | ||
| 159 | it 'calls cattr_reader' do | ||
| 160 | Class.should_receive(:cattr_reader).with('polygons') | ||
| 161 | Class.cattr_accessor('polygons') | ||
| 162 | end | ||
| 163 | |||
| 164 | it 'calls cattr_writer' do | ||
| 165 | Class.should_receive(:cattr_writer).with('polygons') | ||
| 166 | Class.cattr_accessor('polygons') | ||
| 167 | end | ||
| 168 | end | ||
| 169 | |||
| 170 | describe "extends Class" do | ||
| 171 | it 'with cattr_reader' do | ||
| 172 | Class.respond_to?('cattr_reader').should be_true | ||
| 173 | end | ||
| 174 | |||
| 175 | it 'with cattr_writer' do | ||
| 176 | Class.respond_to?('cattr_writer').should be_true | ||
| 177 | end | ||
| 178 | |||
| 179 | it 'with cattr_accessor' do | ||
| 180 | Class.respond_to?('cattr_accessor').should be_true | ||
| 181 | end | ||
| 182 | end | ||
| 183 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/search_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/search_spec.rb new file mode 100644 index 0000000..dd85138 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx/search_spec.rb | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | require 'will_paginate/collection' | ||
| 3 | |||
| 4 | describe ThinkingSphinx::Search do | ||
| 5 | describe "search method" do | ||
| 6 | before :each do | ||
| 7 | @client = Riddle::Client.stub_instance( | ||
| 8 | :filters => [], | ||
| 9 | :filters= => true, | ||
| 10 | :id_range= => true, | ||
| 11 | :sort_mode => :asc, | ||
| 12 | :limit => 5, | ||
| 13 | :offset= => 0, | ||
| 14 | :sort_mode= => true, | ||
| 15 | :query => { | ||
| 16 | :matches => [], | ||
| 17 | :total => 50 | ||
| 18 | } | ||
| 19 | ) | ||
| 20 | |||
| 21 | ThinkingSphinx::Search.stub_methods( | ||
| 22 | :client_from_options => @client, | ||
| 23 | :search_conditions => ["", []] | ||
| 24 | ) | ||
| 25 | end | ||
| 26 | |||
| 27 | describe ":star option" do | ||
| 28 | |||
| 29 | it "should not apply by default" do | ||
| 30 | ThinkingSphinx::Search.search "foo bar" | ||
| 31 | @client.should have_received(:query).with("foo bar") | ||
| 32 | end | ||
| 33 | |||
| 34 | it "should apply when passed, and handle full extended syntax" do | ||
| 35 | input = %{a b* c (d | e) 123 5&6 (f_f g) !h "i j" "k l"~10 "m n"/3 @o p -(q|r)} | ||
| 36 | expected = %{*a* b* *c* (*d* | *e*) *123* *5*&*6* (*f_f* *g*) !*h* "i j" "k l"~10 "m n"/3 @o *p* -(*q*|*r*)} | ||
| 37 | ThinkingSphinx::Search.search input, :star => true | ||
| 38 | @client.should have_received(:query).with(expected) | ||
| 39 | end | ||
| 40 | |||
| 41 | it "should default to /\w+/ as token" do | ||
| 42 | ThinkingSphinx::Search.search "foo@bar.com", :star => true | ||
| 43 | @client.should have_received(:query).with("*foo*@*bar*.*com*") | ||
| 44 | end | ||
| 45 | |||
| 46 | it "should honour custom token" do | ||
| 47 | ThinkingSphinx::Search.search "foo@bar.com -foo-bar", :star => /[\w@.-]+/u | ||
| 48 | @client.should have_received(:query).with("*foo@bar.com* -*foo-bar*") | ||
| 49 | end | ||
| 50 | |||
| 51 | end | ||
| 52 | end | ||
| 53 | end | ||
| 54 | |||
| 55 | describe ThinkingSphinx::Search, "playing nice with Search model" do | ||
| 56 | it "should not conflict with models called Search" do | ||
| 57 | lambda { Search.find(:all) }.should_not raise_error | ||
| 58 | end | ||
| 59 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx_spec.rb b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx_spec.rb new file mode 100644 index 0000000..375e158 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/spec/unit/thinking_sphinx_spec.rb | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | require 'spec/spec_helper' | ||
| 2 | |||
| 3 | describe ThinkingSphinx do | ||
| 4 | it "should define indexes by default" do | ||
| 5 | ThinkingSphinx.define_indexes?.should be_true | ||
| 6 | end | ||
| 7 | |||
| 8 | it "should disable index definition" do | ||
| 9 | ThinkingSphinx.define_indexes = false | ||
| 10 | ThinkingSphinx.define_indexes?.should be_false | ||
| 11 | end | ||
| 12 | |||
| 13 | it "should enable index definition" do | ||
| 14 | ThinkingSphinx.define_indexes = false | ||
| 15 | ThinkingSphinx.define_indexes?.should be_false | ||
| 16 | ThinkingSphinx.define_indexes = true | ||
| 17 | ThinkingSphinx.define_indexes?.should be_true | ||
| 18 | end | ||
| 19 | |||
| 20 | it "should index deltas by default" do | ||
| 21 | ThinkingSphinx.deltas_enabled = nil | ||
| 22 | ThinkingSphinx.deltas_enabled?.should be_true | ||
| 23 | end | ||
| 24 | |||
| 25 | it "should disable delta indexing" do | ||
| 26 | ThinkingSphinx.deltas_enabled = false | ||
| 27 | ThinkingSphinx.deltas_enabled?.should be_false | ||
| 28 | end | ||
| 29 | |||
| 30 | it "should enable delta indexing" do | ||
| 31 | ThinkingSphinx.deltas_enabled = false | ||
| 32 | ThinkingSphinx.deltas_enabled?.should be_false | ||
| 33 | ThinkingSphinx.deltas_enabled = true | ||
| 34 | ThinkingSphinx.deltas_enabled?.should be_true | ||
| 35 | end | ||
| 36 | |||
| 37 | it "should update indexes by default" do | ||
| 38 | ThinkingSphinx.updates_enabled = nil | ||
| 39 | ThinkingSphinx.updates_enabled?.should be_true | ||
| 40 | end | ||
| 41 | |||
| 42 | it "should disable index updating" do | ||
| 43 | ThinkingSphinx.updates_enabled = false | ||
| 44 | ThinkingSphinx.updates_enabled?.should be_false | ||
| 45 | end | ||
| 46 | |||
| 47 | it "should enable index updating" do | ||
| 48 | ThinkingSphinx.updates_enabled = false | ||
| 49 | ThinkingSphinx.updates_enabled?.should be_false | ||
| 50 | ThinkingSphinx.updates_enabled = true | ||
| 51 | ThinkingSphinx.updates_enabled?.should be_true | ||
| 52 | end | ||
| 53 | |||
| 54 | describe "use_group_by_shortcut? method" do | ||
| 55 | before :each do | ||
| 56 | adapter = defined?(JRUBY_VERSION) ? :JdbcAdapter : :MysqlAdapter | ||
| 57 | unless ::ActiveRecord::ConnectionAdapters.const_defined?(adapter) | ||
| 58 | pending "No MySQL" | ||
| 59 | return | ||
| 60 | end | ||
| 61 | |||
| 62 | @connection = ::ActiveRecord::ConnectionAdapters.const_get(adapter).stub_instance( | ||
| 63 | :select_all => true, | ||
| 64 | :config => {:adapter => defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql'} | ||
| 65 | ) | ||
| 66 | ::ActiveRecord::Base.stub_method( | ||
| 67 | :connection => @connection | ||
| 68 | ) | ||
| 69 | end | ||
| 70 | |||
| 71 | it "should return true if no ONLY_FULL_GROUP_BY" do | ||
| 72 | @connection.stub_method( | ||
| 73 | :select_all => {:a => "OTHER SETTINGS"} | ||
| 74 | ) | ||
| 75 | |||
| 76 | ThinkingSphinx.use_group_by_shortcut?.should be_true | ||
| 77 | end | ||
| 78 | |||
| 79 | it "should return true if NULL value" do | ||
| 80 | @connection.stub_method( | ||
| 81 | :select_all => {:a => nil} | ||
| 82 | ) | ||
| 83 | |||
| 84 | ThinkingSphinx.use_group_by_shortcut?.should be_true | ||
| 85 | end | ||
| 86 | |||
| 87 | it "should return false if ONLY_FULL_GROUP_BY is set" do | ||
| 88 | @connection.stub_method( | ||
| 89 | :select_all => {:a => "OTHER SETTINGS,ONLY_FULL_GROUP_BY,blah"} | ||
| 90 | ) | ||
| 91 | |||
| 92 | ThinkingSphinx.use_group_by_shortcut?.should be_false | ||
| 93 | end | ||
| 94 | |||
| 95 | it "should return false if ONLY_FULL_GROUP_BY is set in any of the values" do | ||
| 96 | @connection.stub_method( | ||
| 97 | :select_all => { | ||
| 98 | :a => "OTHER SETTINGS", | ||
| 99 | :b => "ONLY_FULL_GROUP_BY" | ||
| 100 | } | ||
| 101 | ) | ||
| 102 | |||
| 103 | ThinkingSphinx.use_group_by_shortcut?.should be_false | ||
| 104 | end | ||
| 105 | |||
| 106 | describe "if not using MySQL" do | ||
| 107 | before :each do | ||
| 108 | adapter = defined?(JRUBY_VERSION) ? :JdbcAdapter : :PostgreSQLAdapter | ||
| 109 | unless ::ActiveRecord::ConnectionAdapters.const_defined?(adapter) | ||
| 110 | pending "No PostgreSQL" | ||
| 111 | return | ||
| 112 | end | ||
| 113 | @connection = ::ActiveRecord::ConnectionAdapters.const_get(adapter).stub_instance( | ||
| 114 | :select_all => true, | ||
| 115 | :config => {:adapter => defined?(JRUBY_VERSION) ? 'jdbcpostgresql' : 'postgresql'} | ||
| 116 | ) | ||
| 117 | ::ActiveRecord::Base.stub_method( | ||
| 118 | :connection => @connection | ||
| 119 | ) | ||
| 120 | end | ||
| 121 | |||
| 122 | it "should return false" do | ||
| 123 | ThinkingSphinx.use_group_by_shortcut?.should be_false | ||
| 124 | end | ||
| 125 | |||
| 126 | it "should not call select_all" do | ||
| 127 | ThinkingSphinx.use_group_by_shortcut? | ||
| 128 | |||
| 129 | @connection.should_not have_received(:select_all) | ||
| 130 | end | ||
| 131 | end | ||
| 132 | end | ||
| 133 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/tasks/distribution.rb b/vendor/plugins/thinking-sphinx/tasks/distribution.rb new file mode 100644 index 0000000..54ea964 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/tasks/distribution.rb | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | require 'rake/rdoctask' | ||
| 2 | require 'rake/gempackagetask' | ||
| 3 | |||
| 4 | $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib' | ||
| 5 | require 'thinking_sphinx' | ||
| 6 | |||
| 7 | desc 'Generate documentation' | ||
| 8 | Rake::RDocTask.new(:rdoc) do |rdoc| | ||
| 9 | rdoc.rdoc_dir = 'rdoc' | ||
| 10 | rdoc.title = 'Thinking Sphinx - ActiveRecord Sphinx Plugin' | ||
| 11 | rdoc.options << '--line-numbers' << '--inline-source' | ||
| 12 | rdoc.rdoc_files.include('README') | ||
| 13 | rdoc.rdoc_files.include('lib/**/*.rb') | ||
| 14 | end | ||
| 15 | |||
| 16 | spec = Gem::Specification.new do |s| | ||
| 17 | s.name = "thinking-sphinx" | ||
| 18 | s.version = ThinkingSphinx::Version::String | ||
| 19 | s.summary = "A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching." | ||
| 20 | s.description = "A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching." | ||
| 21 | s.author = "Pat Allan" | ||
| 22 | s.email = "pat@freelancing-gods.com" | ||
| 23 | s.homepage = "http://ts.freelancing-gods.com" | ||
| 24 | s.has_rdoc = true | ||
| 25 | s.rdoc_options << "--title" << "Thinking Sphinx -- Rails/Merb Sphinx Plugin" << | ||
| 26 | "--line-numbers" | ||
| 27 | s.rubyforge_project = "thinking-sphinx" | ||
| 28 | s.test_files = FileList["spec/**/*_spec.rb"] | ||
| 29 | s.files = FileList[ | ||
| 30 | "lib/**/*.rb", | ||
| 31 | "LICENCE", | ||
| 32 | "README", | ||
| 33 | "tasks/**/*.rb", | ||
| 34 | "tasks/**/*.rake", | ||
| 35 | "vendor/**/*" | ||
| 36 | ] | ||
| 37 | end | ||
| 38 | |||
| 39 | Rake::GemPackageTask.new(spec) do |p| | ||
| 40 | p.gem_spec = spec | ||
| 41 | p.need_tar = true | ||
| 42 | p.need_zip = true | ||
| 43 | end | ||
| 44 | |||
| 45 | desc "Build gemspec file" | ||
| 46 | task :build do | ||
| 47 | File.open('thinking-sphinx.gemspec', 'w') { |f| f.write spec.to_ruby } | ||
| 48 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/tasks/rails.rake b/vendor/plugins/thinking-sphinx/tasks/rails.rake new file mode 100644 index 0000000..47fa76c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/tasks/rails.rake | |||
| @@ -0,0 +1 @@ | |||
| require File.join(File.dirname(__FILE__), '/../lib/thinking_sphinx/tasks') \ No newline at end of file | |||
diff --git a/vendor/plugins/thinking-sphinx/tasks/testing.rb b/vendor/plugins/thinking-sphinx/tasks/testing.rb new file mode 100644 index 0000000..9cb83ba --- /dev/null +++ b/vendor/plugins/thinking-sphinx/tasks/testing.rb | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | require 'rubygems' | ||
| 2 | require 'spec/rake/spectask' | ||
| 3 | require 'cucumber/rake/task' | ||
| 4 | |||
| 5 | desc "Run the specs under spec" | ||
| 6 | Spec::Rake::SpecTask.new do |t| | ||
| 7 | t.spec_files = FileList['spec/**/*_spec.rb'] | ||
| 8 | t.spec_opts << "-c" | ||
| 9 | end | ||
| 10 | |||
| 11 | desc "Run all feature-set configurations" | ||
| 12 | task :features do |t| | ||
| 13 | puts "rake features:mysql" | ||
| 14 | system "rake features:mysql" | ||
| 15 | puts "rake features:postgresql" | ||
| 16 | system "rake features:postgresql" | ||
| 17 | end | ||
| 18 | |||
| 19 | namespace :features do | ||
| 20 | def add_task(name, description) | ||
| 21 | Cucumber::Rake::Task.new(name, description) do |t| | ||
| 22 | t.cucumber_opts = "--format pretty" | ||
| 23 | t.step_pattern = [ | ||
| 24 | "features/support/env", | ||
| 25 | "features/support/db/#{name}", | ||
| 26 | "features/support/db/active_record", | ||
| 27 | "features/support/post_database", | ||
| 28 | "features/step_definitions/**.rb" | ||
| 29 | ] | ||
| 30 | end | ||
| 31 | end | ||
| 32 | |||
| 33 | add_task :mysql, "Run feature-set against MySQL" | ||
| 34 | add_task :postgresql, "Run feature-set against PostgreSQL" | ||
| 35 | end | ||
| 36 | |||
| 37 | desc "Generate RCov reports" | ||
| 38 | Spec::Rake::SpecTask.new(:rcov) do |t| | ||
| 39 | t.libs << 'lib' | ||
| 40 | t.spec_files = FileList['spec/**/*_spec.rb'] | ||
| 41 | t.rcov = true | ||
| 42 | t.rcov_opts = ['--exclude', 'spec', '--exclude', 'gems', '--exclude', 'riddle'] | ||
| 43 | end | ||
| 44 | |||
| 45 | namespace :rcov do | ||
| 46 | def add_task(name, description) | ||
| 47 | Cucumber::Rake::Task.new(name, description) do |t| | ||
| 48 | t.cucumber_opts = "--format pretty" | ||
| 49 | t.step_pattern = [ | ||
| 50 | "features/support/env", | ||
| 51 | "features/support/db/#{name}", | ||
| 52 | "features/support/db/active_record", | ||
| 53 | "features/support/post_database", | ||
| 54 | "features/step_definitions/**.rb" | ||
| 55 | ] | ||
| 56 | t.rcov = true | ||
| 57 | t.rcov_opts = [ | ||
| 58 | '--exclude', 'spec', | ||
| 59 | '--exclude', 'gems', | ||
| 60 | '--exclude', 'riddle', | ||
| 61 | '--exclude', 'features' | ||
| 62 | ] | ||
| 63 | end | ||
| 64 | end | ||
| 65 | |||
| 66 | add_task :mysql, "Run feature-set against MySQL with rcov" | ||
| 67 | add_task :postgresql, "Run feature-set against PostgreSQL with rcov" | ||
| 68 | end | ||
| 69 | |||
| 70 | desc "Build cucumber.yml file" | ||
| 71 | task :cucumber_defaults do | ||
| 72 | default_requires = %w( | ||
| 73 | --require features/support/env.rb | ||
| 74 | --require features/support/db/mysql.rb | ||
| 75 | --require features/support/db/active_record.rb | ||
| 76 | --require features/support/post_database.rb | ||
| 77 | ).join(" ") | ||
| 78 | |||
| 79 | step_definitions = FileList["features/step_definitions/**.rb"].collect { |path| | ||
| 80 | "--require #{path}" | ||
| 81 | }.join(" ") | ||
| 82 | |||
| 83 | File.open('cucumber.yml', 'w') { |f| | ||
| 84 | f.write "default: \"#{default_requires} #{step_definitions}\"" | ||
| 85 | } | ||
| 86 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/thinking-sphinx.gemspec b/vendor/plugins/thinking-sphinx/thinking-sphinx.gemspec new file mode 100644 index 0000000..39e8503 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/thinking-sphinx.gemspec | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | # -*- encoding: utf-8 -*- | ||
| 2 | |||
| 3 | Gem::Specification.new do |s| | ||
| 4 | s.name = %q{thinking-sphinx} | ||
| 5 | s.version = "1.1.6" | ||
| 6 | |||
| 7 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= | ||
| 8 | s.authors = ["Pat Allan"] | ||
| 9 | s.date = %q{2009-03-11} | ||
| 10 | s.description = %q{A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.} | ||
| 11 | s.email = %q{pat@freelancing-gods.com} | ||
| 12 | s.files = ["lib/thinking_sphinx/active_record/delta.rb", "lib/thinking_sphinx/active_record/has_many_association.rb", "lib/thinking_sphinx/active_record/search.rb", "lib/thinking_sphinx/active_record.rb", "lib/thinking_sphinx/adapters/abstract_adapter.rb", "lib/thinking_sphinx/adapters/mysql_adapter.rb", "lib/thinking_sphinx/adapters/postgresql_adapter.rb", "lib/thinking_sphinx/association.rb", "lib/thinking_sphinx/attribute.rb", "lib/thinking_sphinx/collection.rb", "lib/thinking_sphinx/configuration.rb", "lib/thinking_sphinx/core/string.rb", "lib/thinking_sphinx/deltas/datetime_delta.rb", "lib/thinking_sphinx/deltas/default_delta.rb", "lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb", "lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb", "lib/thinking_sphinx/deltas/delayed_delta/job.rb", "lib/thinking_sphinx/deltas/delayed_delta.rb", "lib/thinking_sphinx/deltas.rb", "lib/thinking_sphinx/facet.rb", "lib/thinking_sphinx/facet_collection.rb", "lib/thinking_sphinx/field.rb", "lib/thinking_sphinx/index/builder.rb", "lib/thinking_sphinx/index/faux_column.rb", "lib/thinking_sphinx/index.rb", "lib/thinking_sphinx/rails_additions.rb", "lib/thinking_sphinx/search.rb", "lib/thinking_sphinx/tasks.rb", "lib/thinking_sphinx.rb", "LICENCE", "README", "tasks/distribution.rb", "tasks/testing.rb", "tasks/rails.rake", "vendor/after_commit", "vendor/after_commit/init.rb", "vendor/after_commit/lib", "vendor/after_commit/lib/after_commit", "vendor/after_commit/lib/after_commit/active_record.rb", "vendor/after_commit/lib/after_commit/connection_adapters.rb", "vendor/after_commit/lib/after_commit.rb", "vendor/after_commit/LICENSE", "vendor/after_commit/Rakefile", "vendor/after_commit/README", "vendor/after_commit/test", "vendor/after_commit/test/after_commit_test.rb", "vendor/delayed_job", "vendor/delayed_job/lib", "vendor/delayed_job/lib/delayed", "vendor/delayed_job/lib/delayed/job.rb", "vendor/delayed_job/lib/delayed/message_sending.rb", "vendor/delayed_job/lib/delayed/performable_method.rb", "vendor/delayed_job/lib/delayed/worker.rb", "vendor/riddle", "vendor/riddle/lib", "vendor/riddle/lib/riddle", "vendor/riddle/lib/riddle/client", "vendor/riddle/lib/riddle/client/filter.rb", "vendor/riddle/lib/riddle/client/message.rb", "vendor/riddle/lib/riddle/client/response.rb", "vendor/riddle/lib/riddle/client.rb", "vendor/riddle/lib/riddle/configuration", "vendor/riddle/lib/riddle/configuration/distributed_index.rb", "vendor/riddle/lib/riddle/configuration/index.rb", "vendor/riddle/lib/riddle/configuration/indexer.rb", "vendor/riddle/lib/riddle/configuration/remote_index.rb", "vendor/riddle/lib/riddle/configuration/searchd.rb", "vendor/riddle/lib/riddle/configuration/section.rb", "vendor/riddle/lib/riddle/configuration/source.rb", "vendor/riddle/lib/riddle/configuration/sql_source.rb", "vendor/riddle/lib/riddle/configuration/xml_source.rb", "vendor/riddle/lib/riddle/configuration.rb", "vendor/riddle/lib/riddle/controller.rb", "vendor/riddle/lib/riddle.rb", "spec/unit/thinking_sphinx/active_record/delta_spec.rb", "spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb", "spec/unit/thinking_sphinx/active_record/search_spec.rb", "spec/unit/thinking_sphinx/active_record_spec.rb", "spec/unit/thinking_sphinx/association_spec.rb", "spec/unit/thinking_sphinx/attribute_spec.rb", "spec/unit/thinking_sphinx/collection_spec.rb", "spec/unit/thinking_sphinx/configuration_spec.rb", "spec/unit/thinking_sphinx/core/string_spec.rb", "spec/unit/thinking_sphinx/field_spec.rb", "spec/unit/thinking_sphinx/index/builder_spec.rb", "spec/unit/thinking_sphinx/index/faux_column_spec.rb", "spec/unit/thinking_sphinx/index_spec.rb", "spec/unit/thinking_sphinx/search_spec.rb", "spec/unit/thinking_sphinx_spec.rb"] | ||
| 13 | s.has_rdoc = true | ||
| 14 | s.homepage = %q{http://ts.freelancing-gods.com} | ||
| 15 | s.rdoc_options = ["--title", "Thinking Sphinx -- Rails/Merb Sphinx Plugin", "--line-numbers"] | ||
| 16 | s.require_paths = ["lib"] | ||
| 17 | s.rubyforge_project = %q{thinking-sphinx} | ||
| 18 | s.rubygems_version = %q{1.3.1} | ||
| 19 | s.summary = %q{A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.} | ||
| 20 | s.test_files = ["spec/unit/thinking_sphinx/active_record/delta_spec.rb", "spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb", "spec/unit/thinking_sphinx/active_record/search_spec.rb", "spec/unit/thinking_sphinx/active_record_spec.rb", "spec/unit/thinking_sphinx/association_spec.rb", "spec/unit/thinking_sphinx/attribute_spec.rb", "spec/unit/thinking_sphinx/collection_spec.rb", "spec/unit/thinking_sphinx/configuration_spec.rb", "spec/unit/thinking_sphinx/core/string_spec.rb", "spec/unit/thinking_sphinx/field_spec.rb", "spec/unit/thinking_sphinx/index/builder_spec.rb", "spec/unit/thinking_sphinx/index/faux_column_spec.rb", "spec/unit/thinking_sphinx/index_spec.rb", "spec/unit/thinking_sphinx/search_spec.rb", "spec/unit/thinking_sphinx_spec.rb"] | ||
| 21 | |||
| 22 | if s.respond_to? :specification_version then | ||
| 23 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION | ||
| 24 | s.specification_version = 2 | ||
| 25 | |||
| 26 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then | ||
| 27 | else | ||
| 28 | end | ||
| 29 | else | ||
| 30 | end | ||
| 31 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/.gitignore b/vendor/plugins/thinking-sphinx/vendor/after_commit/.gitignore new file mode 100644 index 0000000..daabe26 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/.gitignore | |||
| @@ -0,0 +1 @@ | |||
| test.sqlite3 | |||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/LICENSE b/vendor/plugins/thinking-sphinx/vendor/after_commit/LICENSE new file mode 100644 index 0000000..f4913c7 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/LICENSE | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | Copyright (c) 2008 Nick Muerdter | ||
| 2 | |||
| 3 | Permission is hereby granted, free of charge, to any person obtaining | ||
| 4 | a copy of this software and associated documentation files (the | ||
| 5 | "Software"), to deal in the Software without restriction, including | ||
| 6 | without limitation the rights to use, copy, modify, merge, publish, | ||
| 7 | distribute, sublicense, and/or sell copies of the Software, and to | ||
| 8 | permit persons to whom the Software is furnished to do so, subject to | ||
| 9 | the following conditions: | ||
| 10 | |||
| 11 | The above copyright notice and this permission notice shall be | ||
| 12 | included in all copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
| 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
| 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/README b/vendor/plugins/thinking-sphinx/vendor/after_commit/README new file mode 100644 index 0000000..d99d58b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/README | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | after_commit | ||
| 2 | =========== | ||
| 3 | |||
| 4 | A Ruby on Rails plugin to add after_commit callbacks. The callbacks that are provided can be used | ||
| 5 | to trigger events that run only after the entire transaction is complete. This is beneficial | ||
| 6 | in situations where you are doing asynchronous processing and need committed objects. | ||
| 7 | |||
| 8 | The following callbacks are provided: | ||
| 9 | |||
| 10 | * (1) after_commit | ||
| 11 | * (2) after_commit_on_create | ||
| 12 | * (3) after_commit_on_update | ||
| 13 | * (4) after_commit_on_destroy | ||
| 14 | |||
| 15 | The after_commit callback is run for any object that has just been committed. You can obtain finer | ||
| 16 | callback control by using the additional <tt>after_commit_on_*</tt> callbacks. | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/Rakefile b/vendor/plugins/thinking-sphinx/vendor/after_commit/Rakefile new file mode 100644 index 0000000..c481278 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/Rakefile | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | require 'rake' | ||
| 2 | require 'rake/testtask' | ||
| 3 | require 'rake/rdoctask' | ||
| 4 | |||
| 5 | desc 'Default: run unit tests.' | ||
| 6 | task :default => :test | ||
| 7 | |||
| 8 | desc 'Test the after_commit plugin.' | ||
| 9 | Rake::TestTask.new(:test) do |t| | ||
| 10 | t.libs << 'lib' | ||
| 11 | t.pattern = 'test/**/*_test.rb' | ||
| 12 | t.verbose = true | ||
| 13 | end | ||
| 14 | |||
| 15 | desc 'Generate documentation for the after_commit plugin.' | ||
| 16 | Rake::RDocTask.new(:rdoc) do |rdoc| | ||
| 17 | rdoc.rdoc_dir = 'rdoc' | ||
| 18 | rdoc.title = 'AfterCommit' | ||
| 19 | rdoc.options << '--line-numbers' << '--inline-source' | ||
| 20 | rdoc.rdoc_files.include('README') | ||
| 21 | rdoc.rdoc_files.include('lib/**/*.rb') | ||
| 22 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/init.rb b/vendor/plugins/thinking-sphinx/vendor/after_commit/init.rb new file mode 100644 index 0000000..e0e114c --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/init.rb | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | ActiveRecord::Base.send(:include, AfterCommit::ActiveRecord) | ||
| 2 | |||
| 3 | Object.subclasses_of(ActiveRecord::ConnectionAdapters::AbstractAdapter).each do |klass| | ||
| 4 | klass.send(:include, AfterCommit::ConnectionAdapters) | ||
| 5 | end | ||
| 6 | if defined?(JRUBY_VERSION) and defined?(JdbcSpec::MySQL) | ||
| 7 | JdbcSpec::MySQL.send :include, AfterCommit::ConnectionAdapters | ||
| 8 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit.rb b/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit.rb new file mode 100644 index 0000000..285860e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit.rb | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | require 'after_commit/active_record' | ||
| 2 | require 'after_commit/connection_adapters' | ||
| 3 | |||
| 4 | module AfterCommit | ||
| 5 | def self.committed_records | ||
| 6 | @@committed_records ||= [] | ||
| 7 | end | ||
| 8 | |||
| 9 | def self.committed_records=(committed_records) | ||
| 10 | @@committed_records = committed_records | ||
| 11 | end | ||
| 12 | |||
| 13 | def self.committed_records_on_create | ||
| 14 | @@committed_records_on_create ||= [] | ||
| 15 | end | ||
| 16 | |||
| 17 | def self.committed_records_on_create=(committed_records) | ||
| 18 | @@committed_records_on_create = committed_records | ||
| 19 | end | ||
| 20 | |||
| 21 | def self.committed_records_on_update | ||
| 22 | @@committed_records_on_update ||= [] | ||
| 23 | end | ||
| 24 | |||
| 25 | def self.committed_records_on_update=(committed_records) | ||
| 26 | @@committed_records_on_update = committed_records | ||
| 27 | end | ||
| 28 | |||
| 29 | def self.committed_records_on_destroy | ||
| 30 | @@committed_records_on_destroy ||= [] | ||
| 31 | end | ||
| 32 | |||
| 33 | def self.committed_records_on_destroy=(committed_records) | ||
| 34 | @@committed_records_on_destroy = committed_records | ||
| 35 | end | ||
| 36 | end | ||
| 37 | |||
| 38 | ActiveRecord::Base.send(:include, AfterCommit::ActiveRecord) | ||
| 39 | |||
| 40 | Object.subclasses_of(ActiveRecord::ConnectionAdapters::AbstractAdapter).each do |klass| | ||
| 41 | klass.send(:include, AfterCommit::ConnectionAdapters) | ||
| 42 | end | ||
| 43 | if defined?(JRUBY_VERSION) and defined?(JdbcSpec::MySQL) | ||
| 44 | JdbcSpec::MySQL.send :include, AfterCommit::ConnectionAdapters | ||
| 45 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit/active_record.rb b/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit/active_record.rb new file mode 100644 index 0000000..57ea3b2 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit/active_record.rb | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | module AfterCommit | ||
| 2 | module ActiveRecord | ||
| 3 | # Based on the code found in Thinking Sphinx: | ||
| 4 | # http://ts.freelancing-gods.com/ which was based on code written by Eli | ||
| 5 | # Miller: | ||
| 6 | # http://elimiller.blogspot.com/2007/06/proper-cache-expiry-with-aftercommit.html | ||
| 7 | # with slight modification from Joost Hietbrink. And now me! Whew. | ||
| 8 | def self.included(base) | ||
| 9 | base.class_eval do | ||
| 10 | # The define_callbacks method was added post Rails 2.0.2 - if it | ||
| 11 | # doesn't exist, we define the callback manually | ||
| 12 | if respond_to?(:define_callbacks) | ||
| 13 | define_callbacks :after_commit, | ||
| 14 | :after_commit_on_create, | ||
| 15 | :after_commit_on_update, | ||
| 16 | :after_commit_on_destroy | ||
| 17 | else | ||
| 18 | class << self | ||
| 19 | # Handle after_commit callbacks - call all the registered callbacks. | ||
| 20 | def after_commit(*callbacks, &block) | ||
| 21 | callbacks << block if block_given? | ||
| 22 | write_inheritable_array(:after_commit, callbacks) | ||
| 23 | end | ||
| 24 | |||
| 25 | def after_commit_on_create(*callbacks, &block) | ||
| 26 | callbacks << block if block_given? | ||
| 27 | write_inheritable_array(:after_commit_on_create, callbacks) | ||
| 28 | end | ||
| 29 | |||
| 30 | def after_commit_on_update(*callbacks, &block) | ||
| 31 | callbacks << block if block_given? | ||
| 32 | write_inheritable_array(:after_commit_on_update, callbacks) | ||
| 33 | end | ||
| 34 | |||
| 35 | def after_commit_on_destroy(*callbacks, &block) | ||
| 36 | callbacks << block if block_given? | ||
| 37 | write_inheritable_array(:after_commit_on_destroy, callbacks) | ||
| 38 | end | ||
| 39 | end | ||
| 40 | end | ||
| 41 | |||
| 42 | after_save :add_committed_record | ||
| 43 | after_create :add_committed_record_on_create | ||
| 44 | after_update :add_committed_record_on_update | ||
| 45 | after_destroy :add_committed_record_on_destroy | ||
| 46 | |||
| 47 | # We need to keep track of records that have been saved or destroyed | ||
| 48 | # within this transaction. | ||
| 49 | def add_committed_record | ||
| 50 | AfterCommit.committed_records << self | ||
| 51 | end | ||
| 52 | |||
| 53 | def add_committed_record_on_create | ||
| 54 | AfterCommit.committed_records_on_create << self | ||
| 55 | end | ||
| 56 | |||
| 57 | def add_committed_record_on_update | ||
| 58 | AfterCommit.committed_records_on_update << self | ||
| 59 | end | ||
| 60 | |||
| 61 | def add_committed_record_on_destroy | ||
| 62 | AfterCommit.committed_records << self | ||
| 63 | AfterCommit.committed_records_on_destroy << self | ||
| 64 | end | ||
| 65 | |||
| 66 | def after_commit | ||
| 67 | # Deliberately blank. | ||
| 68 | end | ||
| 69 | |||
| 70 | # Wraps a call to the private callback method so that the the | ||
| 71 | # after_commit callback can be made from the ConnectionAdapters when | ||
| 72 | # the commit for the transaction has finally succeeded. | ||
| 73 | def after_commit_callback | ||
| 74 | call_after_commit_callback :after_commit | ||
| 75 | end | ||
| 76 | |||
| 77 | def after_commit_on_create_callback | ||
| 78 | call_after_commit_callback :after_commit_on_create | ||
| 79 | end | ||
| 80 | |||
| 81 | def after_commit_on_update_callback | ||
| 82 | call_after_commit_callback :after_commit_on_update | ||
| 83 | end | ||
| 84 | |||
| 85 | def after_commit_on_destroy_callback | ||
| 86 | call_after_commit_callback :after_commit_on_destroy | ||
| 87 | end | ||
| 88 | |||
| 89 | private | ||
| 90 | |||
| 91 | def call_after_commit_callback(call) | ||
| 92 | if can_call_after_commit call | ||
| 93 | callback call | ||
| 94 | clear_after_commit_call call | ||
| 95 | end | ||
| 96 | end | ||
| 97 | |||
| 98 | def can_call_after_commit(call) | ||
| 99 | @calls ||= {} | ||
| 100 | @calls[call] ||= false | ||
| 101 | if @calls[call] | ||
| 102 | return false | ||
| 103 | else | ||
| 104 | @calls[call] = true | ||
| 105 | end | ||
| 106 | end | ||
| 107 | |||
| 108 | def clear_after_commit_call(call) | ||
| 109 | @calls[call] = false | ||
| 110 | end | ||
| 111 | end | ||
| 112 | end | ||
| 113 | end | ||
| 114 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit/connection_adapters.rb b/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit/connection_adapters.rb new file mode 100644 index 0000000..86e2b6e --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/lib/after_commit/connection_adapters.rb | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | module AfterCommit | ||
| 2 | module ConnectionAdapters | ||
| 3 | def self.included(base) | ||
| 4 | base.class_eval do | ||
| 5 | # The commit_db_transaction method gets called when the outermost | ||
| 6 | # transaction finishes and everything inside commits. We want to | ||
| 7 | # override it so that after this happens, any records that were saved | ||
| 8 | # or destroyed within this transaction now get their after_commit | ||
| 9 | # callback fired. | ||
| 10 | def commit_db_transaction_with_callback | ||
| 11 | commit_db_transaction_without_callback | ||
| 12 | trigger_after_commit_callbacks | ||
| 13 | trigger_after_commit_on_create_callbacks | ||
| 14 | trigger_after_commit_on_update_callbacks | ||
| 15 | trigger_after_commit_on_destroy_callbacks | ||
| 16 | end | ||
| 17 | alias_method_chain :commit_db_transaction, :callback | ||
| 18 | |||
| 19 | # In the event the transaction fails and rolls back, nothing inside | ||
| 20 | # should recieve the after_commit callback. | ||
| 21 | def rollback_db_transaction_with_callback | ||
| 22 | rollback_db_transaction_without_callback | ||
| 23 | |||
| 24 | AfterCommit.committed_records = [] | ||
| 25 | AfterCommit.committed_records_on_create = [] | ||
| 26 | AfterCommit.committed_records_on_update = [] | ||
| 27 | AfterCommit.committed_records_on_destroy = [] | ||
| 28 | end | ||
| 29 | alias_method_chain :rollback_db_transaction, :callback | ||
| 30 | |||
| 31 | protected | ||
| 32 | def trigger_after_commit_callbacks | ||
| 33 | # Trigger the after_commit callback for each of the committed | ||
| 34 | # records. | ||
| 35 | if AfterCommit.committed_records.any? | ||
| 36 | AfterCommit.committed_records.each do |record| | ||
| 37 | begin | ||
| 38 | record.after_commit_callback | ||
| 39 | rescue | ||
| 40 | end | ||
| 41 | end | ||
| 42 | end | ||
| 43 | |||
| 44 | # Make sure we clear out our list of committed records now that we've | ||
| 45 | # triggered the callbacks for each one. | ||
| 46 | AfterCommit.committed_records = [] | ||
| 47 | end | ||
| 48 | |||
| 49 | def trigger_after_commit_on_create_callbacks | ||
| 50 | # Trigger the after_commit_on_create callback for each of the committed | ||
| 51 | # records. | ||
| 52 | if AfterCommit.committed_records_on_create.any? | ||
| 53 | AfterCommit.committed_records_on_create.each do |record| | ||
| 54 | begin | ||
| 55 | record.after_commit_on_create_callback | ||
| 56 | rescue | ||
| 57 | end | ||
| 58 | end | ||
| 59 | end | ||
| 60 | |||
| 61 | # Make sure we clear out our list of committed records now that we've | ||
| 62 | # triggered the callbacks for each one. | ||
| 63 | AfterCommit.committed_records_on_create = [] | ||
| 64 | end | ||
| 65 | |||
| 66 | def trigger_after_commit_on_update_callbacks | ||
| 67 | # Trigger the after_commit_on_update callback for each of the committed | ||
| 68 | # records. | ||
| 69 | if AfterCommit.committed_records_on_update.any? | ||
| 70 | AfterCommit.committed_records_on_update.each do |record| | ||
| 71 | begin | ||
| 72 | record.after_commit_on_update_callback | ||
| 73 | rescue | ||
| 74 | end | ||
| 75 | end | ||
| 76 | end | ||
| 77 | |||
| 78 | # Make sure we clear out our list of committed records now that we've | ||
| 79 | # triggered the callbacks for each one. | ||
| 80 | AfterCommit.committed_records_on_update = [] | ||
| 81 | end | ||
| 82 | |||
| 83 | def trigger_after_commit_on_destroy_callbacks | ||
| 84 | # Trigger the after_commit_on_destroy callback for each of the committed | ||
| 85 | # records. | ||
| 86 | if AfterCommit.committed_records_on_destroy.any? | ||
| 87 | AfterCommit.committed_records_on_destroy.each do |record| | ||
| 88 | begin | ||
| 89 | record.after_commit_on_destroy_callback | ||
| 90 | rescue | ||
| 91 | end | ||
| 92 | end | ||
| 93 | end | ||
| 94 | |||
| 95 | # Make sure we clear out our list of committed records now that we've | ||
| 96 | # triggered the callbacks for each one. | ||
| 97 | AfterCommit.committed_records_on_destroy = [] | ||
| 98 | end | ||
| 99 | #end protected | ||
| 100 | end | ||
| 101 | end | ||
| 102 | end | ||
| 103 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/after_commit/test/after_commit_test.rb b/vendor/plugins/thinking-sphinx/vendor/after_commit/test/after_commit_test.rb new file mode 100644 index 0000000..f8b42cd --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/after_commit/test/after_commit_test.rb | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib') | ||
| 2 | require 'test/unit' | ||
| 3 | require 'rubygems' | ||
| 4 | require 'activerecord' | ||
| 5 | require 'after_commit' | ||
| 6 | require 'after_commit/active_record' | ||
| 7 | require 'after_commit/connection_adapters' | ||
| 8 | |||
| 9 | ActiveRecord::Base.establish_connection({"adapter" => "sqlite3", "database" => 'test.sqlite3'}) | ||
| 10 | begin | ||
| 11 | ActiveRecord::Base.connection.execute("drop table mock_records"); | ||
| 12 | rescue | ||
| 13 | end | ||
| 14 | ActiveRecord::Base.connection.execute("create table mock_records(id int)"); | ||
| 15 | |||
| 16 | require File.dirname(__FILE__) + '/../init.rb' | ||
| 17 | |||
| 18 | class MockRecord < ActiveRecord::Base | ||
| 19 | attr_accessor :after_commit_on_create_called | ||
| 20 | attr_accessor :after_commit_on_update_called | ||
| 21 | attr_accessor :after_commit_on_destroy_called | ||
| 22 | |||
| 23 | after_commit_on_create :do_create | ||
| 24 | def do_create | ||
| 25 | self.after_commit_on_create_called = true | ||
| 26 | end | ||
| 27 | |||
| 28 | after_commit_on_update :do_update | ||
| 29 | def do_update | ||
| 30 | self.after_commit_on_update_called = true | ||
| 31 | end | ||
| 32 | |||
| 33 | after_commit_on_create :do_destroy | ||
| 34 | def do_destroy | ||
| 35 | self.after_commit_on_destroy_called = true | ||
| 36 | end | ||
| 37 | end | ||
| 38 | |||
| 39 | class AfterCommitTest < Test::Unit::TestCase | ||
| 40 | def test_after_commit_on_create_is_called | ||
| 41 | assert_equal true, MockRecord.create!.after_commit_on_create_called | ||
| 42 | end | ||
| 43 | |||
| 44 | def test_after_commit_on_update_is_called | ||
| 45 | record = MockRecord.create! | ||
| 46 | record.save | ||
| 47 | assert_equal true, record.after_commit_on_update_called | ||
| 48 | end | ||
| 49 | |||
| 50 | def test_after_commit_on_destroy_is_called | ||
| 51 | assert_equal true, MockRecord.create!.destroy.after_commit_on_destroy_called | ||
| 52 | end | ||
| 53 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/job.rb b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/job.rb new file mode 100644 index 0000000..cb62bab --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/job.rb | |||
| @@ -0,0 +1,251 @@ | |||
| 1 | module Delayed | ||
| 2 | |||
| 3 | class DeserializationError < StandardError | ||
| 4 | end | ||
| 5 | |||
| 6 | class Job < ActiveRecord::Base | ||
| 7 | MAX_ATTEMPTS = 25 | ||
| 8 | MAX_RUN_TIME = 4.hours | ||
| 9 | set_table_name :delayed_jobs | ||
| 10 | |||
| 11 | # By default failed jobs are destroyed after too many attempts. | ||
| 12 | # If you want to keep them around (perhaps to inspect the reason | ||
| 13 | # for the failure), set this to false. | ||
| 14 | cattr_accessor :destroy_failed_jobs | ||
| 15 | self.destroy_failed_jobs = true | ||
| 16 | |||
| 17 | # Every worker has a unique name which by default is the pid of the process. | ||
| 18 | # There are some advantages to overriding this with something which survives worker retarts: | ||
| 19 | # Workers can safely resume working on tasks which are locked by themselves. The worker will assume that it crashed before. | ||
| 20 | cattr_accessor :worker_name | ||
| 21 | self.worker_name = "host:#{Socket.gethostname} pid:#{Process.pid}" rescue "pid:#{Process.pid}" | ||
| 22 | |||
| 23 | NextTaskSQL = '(run_at <= ? AND (locked_at IS NULL OR locked_at < ?) OR (locked_by = ?)) AND failed_at IS NULL' | ||
| 24 | NextTaskOrder = 'priority DESC, run_at ASC' | ||
| 25 | |||
| 26 | ParseObjectFromYaml = /\!ruby\/\w+\:([^\s]+)/ | ||
| 27 | |||
| 28 | cattr_accessor :min_priority, :max_priority | ||
| 29 | self.min_priority = nil | ||
| 30 | self.max_priority = nil | ||
| 31 | |||
| 32 | class LockError < StandardError | ||
| 33 | end | ||
| 34 | |||
| 35 | def self.clear_locks! | ||
| 36 | update_all("locked_by = null, locked_at = null", ["locked_by = ?", worker_name]) | ||
| 37 | end | ||
| 38 | |||
| 39 | def failed? | ||
| 40 | failed_at | ||
| 41 | end | ||
| 42 | alias_method :failed, :failed? | ||
| 43 | |||
| 44 | def payload_object | ||
| 45 | @payload_object ||= deserialize(self['handler']) | ||
| 46 | end | ||
| 47 | |||
| 48 | def name | ||
| 49 | @name ||= begin | ||
| 50 | payload = payload_object | ||
| 51 | if payload.respond_to?(:display_name) | ||
| 52 | payload.display_name | ||
| 53 | else | ||
| 54 | payload.class.name | ||
| 55 | end | ||
| 56 | end | ||
| 57 | end | ||
| 58 | |||
| 59 | def payload_object=(object) | ||
| 60 | self['handler'] = object.to_yaml | ||
| 61 | end | ||
| 62 | |||
| 63 | def reschedule(message, backtrace = [], time = nil) | ||
| 64 | if self.attempts < MAX_ATTEMPTS | ||
| 65 | time ||= Job.db_time_now + (attempts ** 4) + 5 | ||
| 66 | |||
| 67 | self.attempts += 1 | ||
| 68 | self.run_at = time | ||
| 69 | self.last_error = message + "\n" + backtrace.join("\n") | ||
| 70 | self.unlock | ||
| 71 | save! | ||
| 72 | else | ||
| 73 | logger.info "* [JOB] PERMANENTLY removing #{self.name} because of #{attempts} consequetive failures." | ||
| 74 | destroy_failed_jobs ? destroy : update_attribute(:failed_at, Time.now) | ||
| 75 | end | ||
| 76 | end | ||
| 77 | |||
| 78 | def self.enqueue(*args, &block) | ||
| 79 | object = block_given? ? EvaledJob.new(&block) : args.shift | ||
| 80 | |||
| 81 | unless object.respond_to?(:perform) || block_given? | ||
| 82 | raise ArgumentError, 'Cannot enqueue items which do not respond to perform' | ||
| 83 | end | ||
| 84 | |||
| 85 | priority = args[0] || 0 | ||
| 86 | run_at = args[1] | ||
| 87 | |||
| 88 | Job.create(:payload_object => object, :priority => priority.to_i, :run_at => run_at) | ||
| 89 | end | ||
| 90 | |||
| 91 | def self.find_available(limit = 5, max_run_time = MAX_RUN_TIME) | ||
| 92 | |||
| 93 | time_now = db_time_now | ||
| 94 | |||
| 95 | sql = NextTaskSQL.dup | ||
| 96 | |||
| 97 | conditions = [time_now, time_now - max_run_time, worker_name] | ||
| 98 | |||
| 99 | if self.min_priority | ||
| 100 | sql << ' AND (priority >= ?)' | ||
| 101 | conditions << min_priority | ||
| 102 | end | ||
| 103 | |||
| 104 | if self.max_priority | ||
| 105 | sql << ' AND (priority <= ?)' | ||
| 106 | conditions << max_priority | ||
| 107 | end | ||
| 108 | |||
| 109 | conditions.unshift(sql) | ||
| 110 | |||
| 111 | records = ActiveRecord::Base.silence do | ||
| 112 | find(:all, :conditions => conditions, :order => NextTaskOrder, :limit => limit) | ||
| 113 | end | ||
| 114 | |||
| 115 | records.sort_by { rand() } | ||
| 116 | end | ||
| 117 | |||
| 118 | # Get the payload of the next job we can get an exclusive lock on. | ||
| 119 | # If no jobs are left we return nil | ||
| 120 | def self.reserve(max_run_time = MAX_RUN_TIME, &block) | ||
| 121 | |||
| 122 | # We get up to 5 jobs from the db. In face we cannot get exclusive access to a job we try the next. | ||
| 123 | # this leads to a more even distribution of jobs across the worker processes | ||
| 124 | find_available(5, max_run_time).each do |job| | ||
| 125 | begin | ||
| 126 | logger.info "* [JOB] aquiring lock on #{job.name}" | ||
| 127 | job.lock_exclusively!(max_run_time, worker_name) | ||
| 128 | runtime = Benchmark.realtime do | ||
| 129 | invoke_job(job.payload_object, &block) | ||
| 130 | job.destroy | ||
| 131 | end | ||
| 132 | logger.info "* [JOB] #{job.name} completed after %.4f" % runtime | ||
| 133 | |||
| 134 | return job | ||
| 135 | rescue LockError | ||
| 136 | # We did not get the lock, some other worker process must have | ||
| 137 | logger.warn "* [JOB] failed to aquire exclusive lock for #{job.name}" | ||
| 138 | rescue StandardError => e | ||
| 139 | job.reschedule e.message, e.backtrace | ||
| 140 | log_exception(job, e) | ||
| 141 | return job | ||
| 142 | end | ||
| 143 | end | ||
| 144 | |||
| 145 | nil | ||
| 146 | end | ||
| 147 | |||
| 148 | # This method is used internally by reserve method to ensure exclusive access | ||
| 149 | # to the given job. It will rise a LockError if it cannot get this lock. | ||
| 150 | def lock_exclusively!(max_run_time, worker = worker_name) | ||
| 151 | now = self.class.db_time_now | ||
| 152 | affected_rows = if locked_by != worker | ||
| 153 | # We don't own this job so we will update the locked_by name and the locked_at | ||
| 154 | self.class.update_all(["locked_at = ?, locked_by = ?", now, worker], ["id = ? and (locked_at is null or locked_at < ?)", id, (now - max_run_time.to_i)]) | ||
| 155 | else | ||
| 156 | # We already own this job, this may happen if the job queue crashes. | ||
| 157 | # Simply resume and update the locked_at | ||
| 158 | self.class.update_all(["locked_at = ?", now], ["id = ? and locked_by = ?", id, worker]) | ||
| 159 | end | ||
| 160 | raise LockError.new("Attempted to aquire exclusive lock failed") unless affected_rows == 1 | ||
| 161 | |||
| 162 | self.locked_at = now | ||
| 163 | self.locked_by = worker | ||
| 164 | end | ||
| 165 | |||
| 166 | def unlock | ||
| 167 | self.locked_at = nil | ||
| 168 | self.locked_by = nil | ||
| 169 | end | ||
| 170 | |||
| 171 | # This is a good hook if you need to report job processing errors in additional or different ways | ||
| 172 | def self.log_exception(job, error) | ||
| 173 | logger.error "* [JOB] #{job.name} failed with #{error.class.name}: #{error.message} - #{job.attempts} failed attempts" | ||
| 174 | logger.error(error) | ||
| 175 | end | ||
| 176 | |||
| 177 | def self.work_off(num = 100) | ||
| 178 | success, failure = 0, 0 | ||
| 179 | |||
| 180 | num.times do | ||
| 181 | job = self.reserve do |j| | ||
| 182 | begin | ||
| 183 | j.perform | ||
| 184 | success += 1 | ||
| 185 | rescue | ||
| 186 | failure += 1 | ||
| 187 | raise | ||
| 188 | end | ||
| 189 | end | ||
| 190 | |||
| 191 | break if job.nil? | ||
| 192 | end | ||
| 193 | |||
| 194 | return [success, failure] | ||
| 195 | end | ||
| 196 | |||
| 197 | # Moved into its own method so that new_relic can trace it. | ||
| 198 | def self.invoke_job(job, &block) | ||
| 199 | block.call(job) | ||
| 200 | end | ||
| 201 | |||
| 202 | private | ||
| 203 | |||
| 204 | def deserialize(source) | ||
| 205 | handler = YAML.load(source) rescue nil | ||
| 206 | |||
| 207 | unless handler.respond_to?(:perform) | ||
| 208 | if handler.nil? && source =~ ParseObjectFromYaml | ||
| 209 | handler_class = $1 | ||
| 210 | end | ||
| 211 | attempt_to_load(handler_class || handler.class) | ||
| 212 | handler = YAML.load(source) | ||
| 213 | end | ||
| 214 | |||
| 215 | return handler if handler.respond_to?(:perform) | ||
| 216 | |||
| 217 | raise DeserializationError, | ||
| 218 | 'Job failed to load: Unknown handler. Try to manually require the appropiate file.' | ||
| 219 | rescue TypeError, LoadError, NameError => e | ||
| 220 | raise DeserializationError, | ||
| 221 | "Job failed to load: #{e.message}. Try to manually require the required file." | ||
| 222 | end | ||
| 223 | |||
| 224 | # Constantize the object so that ActiveSupport can attempt | ||
| 225 | # its auto loading magic. Will raise LoadError if not successful. | ||
| 226 | def attempt_to_load(klass) | ||
| 227 | klass.constantize | ||
| 228 | end | ||
| 229 | |||
| 230 | def self.db_time_now | ||
| 231 | (ActiveRecord::Base.default_timezone == :utc) ? Time.now.utc : Time.now | ||
| 232 | end | ||
| 233 | |||
| 234 | protected | ||
| 235 | |||
| 236 | def before_save | ||
| 237 | self.run_at ||= self.class.db_time_now | ||
| 238 | end | ||
| 239 | |||
| 240 | end | ||
| 241 | |||
| 242 | class EvaledJob | ||
| 243 | def initialize | ||
| 244 | @job = yield | ||
| 245 | end | ||
| 246 | |||
| 247 | def perform | ||
| 248 | eval(@job) | ||
| 249 | end | ||
| 250 | end | ||
| 251 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/message_sending.rb b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/message_sending.rb new file mode 100644 index 0000000..80a02f3 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/message_sending.rb | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | module Delayed | ||
| 2 | module MessageSending | ||
| 3 | def send_later(method, *args) | ||
| 4 | Delayed::Job.enqueue Delayed::PerformableMethod.new(self, method.to_sym, args) | ||
| 5 | end | ||
| 6 | end | ||
| 7 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/performable_method.rb b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/performable_method.rb new file mode 100644 index 0000000..18bc77a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/performable_method.rb | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | module Delayed | ||
| 2 | class PerformableMethod < Struct.new(:object, :method, :args) | ||
| 3 | CLASS_STRING_FORMAT = /^CLASS\:([A-Z][\w\:]+)$/ | ||
| 4 | AR_STRING_FORMAT = /^AR\:([A-Z][\w\:]+)\:(\d+)$/ | ||
| 5 | |||
| 6 | def initialize(object, method, args) | ||
| 7 | raise NoMethodError, "undefined method `#{method}' for #{self.inspect}" unless object.respond_to?(method) | ||
| 8 | |||
| 9 | self.object = dump(object) | ||
| 10 | self.args = args.map { |a| dump(a) } | ||
| 11 | self.method = method.to_sym | ||
| 12 | end | ||
| 13 | |||
| 14 | def display_name | ||
| 15 | case self.object | ||
| 16 | when CLASS_STRING_FORMAT then "#{$1}.#{method}" | ||
| 17 | when AR_STRING_FORMAT then "#{$1}##{method}" | ||
| 18 | else "Unknown##{method}" | ||
| 19 | end | ||
| 20 | end | ||
| 21 | |||
| 22 | def perform | ||
| 23 | load(object).send(method, *args.map{|a| load(a)}) | ||
| 24 | rescue ActiveRecord::RecordNotFound | ||
| 25 | # We cannot do anything about objects which were deleted in the meantime | ||
| 26 | true | ||
| 27 | end | ||
| 28 | |||
| 29 | private | ||
| 30 | |||
| 31 | def load(arg) | ||
| 32 | case arg | ||
| 33 | when CLASS_STRING_FORMAT then $1.constantize | ||
| 34 | when AR_STRING_FORMAT then $1.constantize.find($2) | ||
| 35 | else arg | ||
| 36 | end | ||
| 37 | end | ||
| 38 | |||
| 39 | def dump(arg) | ||
| 40 | case arg | ||
| 41 | when Class then class_to_string(arg) | ||
| 42 | when ActiveRecord::Base then ar_to_string(arg) | ||
| 43 | else arg | ||
| 44 | end | ||
| 45 | end | ||
| 46 | |||
| 47 | def ar_to_string(obj) | ||
| 48 | "AR:#{obj.class}:#{obj.id}" | ||
| 49 | end | ||
| 50 | |||
| 51 | def class_to_string(obj) | ||
| 52 | "CLASS:#{obj.name}" | ||
| 53 | end | ||
| 54 | end | ||
| 55 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/worker.rb b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/worker.rb new file mode 100644 index 0000000..9ae6726 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/delayed_job/lib/delayed/worker.rb | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | module Delayed | ||
| 2 | class Worker | ||
| 3 | SLEEP = 5 | ||
| 4 | |||
| 5 | cattr_accessor :logger | ||
| 6 | self.logger = if defined?(Merb::Logger) | ||
| 7 | Merb.logger | ||
| 8 | elsif defined?(RAILS_DEFAULT_LOGGER) | ||
| 9 | RAILS_DEFAULT_LOGGER | ||
| 10 | end | ||
| 11 | |||
| 12 | def initialize(options={}) | ||
| 13 | @quiet = options[:quiet] | ||
| 14 | Delayed::Job.min_priority = options[:min_priority] if options.has_key?(:min_priority) | ||
| 15 | Delayed::Job.max_priority = options[:max_priority] if options.has_key?(:max_priority) | ||
| 16 | end | ||
| 17 | |||
| 18 | def start | ||
| 19 | say "*** Starting job worker #{Delayed::Job.worker_name}" | ||
| 20 | |||
| 21 | trap('TERM') { say 'Exiting...'; $exit = true } | ||
| 22 | trap('INT') { say 'Exiting...'; $exit = true } | ||
| 23 | |||
| 24 | loop do | ||
| 25 | result = nil | ||
| 26 | |||
| 27 | realtime = Benchmark.realtime do | ||
| 28 | result = Delayed::Job.work_off | ||
| 29 | end | ||
| 30 | |||
| 31 | count = result.sum | ||
| 32 | |||
| 33 | break if $exit | ||
| 34 | |||
| 35 | if count.zero? | ||
| 36 | sleep(SLEEP) | ||
| 37 | else | ||
| 38 | say "#{count} jobs processed at %.4f j/s, %d failed ..." % [count / realtime, result.last] | ||
| 39 | end | ||
| 40 | |||
| 41 | break if $exit | ||
| 42 | end | ||
| 43 | |||
| 44 | ensure | ||
| 45 | Delayed::Job.clear_locks! | ||
| 46 | end | ||
| 47 | |||
| 48 | def say(text) | ||
| 49 | puts text unless @quiet | ||
| 50 | logger.info text if logger | ||
| 51 | end | ||
| 52 | |||
| 53 | end | ||
| 54 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle.rb new file mode 100644 index 0000000..2f1801a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle.rb | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | require 'socket' | ||
| 2 | require 'timeout' | ||
| 3 | |||
| 4 | require 'riddle/client' | ||
| 5 | require 'riddle/configuration' | ||
| 6 | require 'riddle/controller' | ||
| 7 | |||
| 8 | module Riddle #:nodoc: | ||
| 9 | class ConnectionError < StandardError #:nodoc: | ||
| 10 | end | ||
| 11 | |||
| 12 | module Version #:nodoc: | ||
| 13 | Major = 0 | ||
| 14 | Minor = 9 | ||
| 15 | Tiny = 8 | ||
| 16 | # Revision number for RubyForge's sake, taken from what Sphinx | ||
| 17 | # outputs to the command line. | ||
| 18 | Rev = 1533 | ||
| 19 | # Release number to mark my own fixes, beyond feature parity with | ||
| 20 | # Sphinx itself. | ||
| 21 | Release = 4 | ||
| 22 | |||
| 23 | String = [Major, Minor, Tiny].join('.') | ||
| 24 | GemVersion = [Major, Minor, Tiny, Rev, Release].join('.') | ||
| 25 | end | ||
| 26 | |||
| 27 | def self.escape(string) | ||
| 28 | string.gsub(/[\(\)\|\-!@~"&\/]/) { |char| "\\#{char}" } | ||
| 29 | end | ||
| 30 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client.rb new file mode 100644 index 0000000..1895bba --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client.rb | |||
| @@ -0,0 +1,619 @@ | |||
| 1 | require 'riddle/client/filter' | ||
| 2 | require 'riddle/client/message' | ||
| 3 | require 'riddle/client/response' | ||
| 4 | |||
| 5 | module Riddle | ||
| 6 | class VersionError < StandardError; end | ||
| 7 | class ResponseError < StandardError; end | ||
| 8 | |||
| 9 | # This class was heavily based on the existing Client API by Dmytro Shteflyuk | ||
| 10 | # and Alexy Kovyrin. Their code worked fine, I just wanted something a bit | ||
| 11 | # more Ruby-ish (ie. lowercase and underscored method names). I also have | ||
| 12 | # used a few helper classes, just to neaten things up. | ||
| 13 | # | ||
| 14 | # Feel free to use it wherever. Send bug reports, patches, comments and | ||
| 15 | # suggestions to pat at freelancing-gods dot com. | ||
| 16 | # | ||
| 17 | # Most properties of the client are accessible through attribute accessors, | ||
| 18 | # and where relevant use symboles instead of the long constants common in | ||
| 19 | # other clients. | ||
| 20 | # Some examples: | ||
| 21 | # | ||
| 22 | # client.sort_mode = :extended | ||
| 23 | # client.sort_by = "birthday DESC" | ||
| 24 | # client.match_mode = :extended | ||
| 25 | # | ||
| 26 | # To add a filter, you will need to create a Filter object: | ||
| 27 | # | ||
| 28 | # client.filters << Riddle::Client::Filter.new("birthday", | ||
| 29 | # Time.at(1975, 1, 1).to_i..Time.at(1985, 1, 1).to_i, false) | ||
| 30 | # | ||
| 31 | class Client | ||
| 32 | Commands = { | ||
| 33 | :search => 0, # SEARCHD_COMMAND_SEARCH | ||
| 34 | :excerpt => 1, # SEARCHD_COMMAND_EXCERPT | ||
| 35 | :update => 2, # SEARCHD_COMMAND_UPDATE | ||
| 36 | :keywords => 3 # SEARCHD_COMMAND_KEYWORDS | ||
| 37 | } | ||
| 38 | |||
| 39 | Versions = { | ||
| 40 | :search => 0x113, # VER_COMMAND_SEARCH | ||
| 41 | :excerpt => 0x100, # VER_COMMAND_EXCERPT | ||
| 42 | :update => 0x101, # VER_COMMAND_UPDATE | ||
| 43 | :keywords => 0x100 # VER_COMMAND_KEYWORDS | ||
| 44 | } | ||
| 45 | |||
| 46 | Statuses = { | ||
| 47 | :ok => 0, # SEARCHD_OK | ||
| 48 | :error => 1, # SEARCHD_ERROR | ||
| 49 | :retry => 2, # SEARCHD_RETRY | ||
| 50 | :warning => 3 # SEARCHD_WARNING | ||
| 51 | } | ||
| 52 | |||
| 53 | MatchModes = { | ||
| 54 | :all => 0, # SPH_MATCH_ALL | ||
| 55 | :any => 1, # SPH_MATCH_ANY | ||
| 56 | :phrase => 2, # SPH_MATCH_PHRASE | ||
| 57 | :boolean => 3, # SPH_MATCH_BOOLEAN | ||
| 58 | :extended => 4, # SPH_MATCH_EXTENDED | ||
| 59 | :fullscan => 5, # SPH_MATCH_FULLSCAN | ||
| 60 | :extended2 => 6 # SPH_MATCH_EXTENDED2 | ||
| 61 | } | ||
| 62 | |||
| 63 | RankModes = { | ||
| 64 | :proximity_bm25 => 0, # SPH_RANK_PROXIMITY_BM25 | ||
| 65 | :bm25 => 1, # SPH_RANK_BM25 | ||
| 66 | :none => 2, # SPH_RANK_NONE | ||
| 67 | :wordcount => 3 # SPH_RANK_WORDCOUNT | ||
| 68 | } | ||
| 69 | |||
| 70 | SortModes = { | ||
| 71 | :relevance => 0, # SPH_SORT_RELEVANCE | ||
| 72 | :attr_desc => 1, # SPH_SORT_ATTR_DESC | ||
| 73 | :attr_asc => 2, # SPH_SORT_ATTR_ASC | ||
| 74 | :time_segments => 3, # SPH_SORT_TIME_SEGMENTS | ||
| 75 | :extended => 4, # SPH_SORT_EXTENDED | ||
| 76 | :expr => 5 # SPH_SORT_EXPR | ||
| 77 | } | ||
| 78 | |||
| 79 | AttributeTypes = { | ||
| 80 | :integer => 1, # SPH_ATTR_INTEGER | ||
| 81 | :timestamp => 2, # SPH_ATTR_TIMESTAMP | ||
| 82 | :ordinal => 3, # SPH_ATTR_ORDINAL | ||
| 83 | :bool => 4, # SPH_ATTR_BOOL | ||
| 84 | :float => 5, # SPH_ATTR_FLOAT | ||
| 85 | :multi => 0x40000000 # SPH_ATTR_MULTI | ||
| 86 | } | ||
| 87 | |||
| 88 | GroupFunctions = { | ||
| 89 | :day => 0, # SPH_GROUPBY_DAY | ||
| 90 | :week => 1, # SPH_GROUPBY_WEEK | ||
| 91 | :month => 2, # SPH_GROUPBY_MONTH | ||
| 92 | :year => 3, # SPH_GROUPBY_YEAR | ||
| 93 | :attr => 4, # SPH_GROUPBY_ATTR | ||
| 94 | :attrpair => 5 # SPH_GROUPBY_ATTRPAIR | ||
| 95 | } | ||
| 96 | |||
| 97 | FilterTypes = { | ||
| 98 | :values => 0, # SPH_FILTER_VALUES | ||
| 99 | :range => 1, # SPH_FILTER_RANGE | ||
| 100 | :float_range => 2 # SPH_FILTER_FLOATRANGE | ||
| 101 | } | ||
| 102 | |||
| 103 | attr_accessor :server, :port, :offset, :limit, :max_matches, | ||
| 104 | :match_mode, :sort_mode, :sort_by, :weights, :id_range, :filters, | ||
| 105 | :group_by, :group_function, :group_clause, :group_distinct, :cut_off, | ||
| 106 | :retry_count, :retry_delay, :anchor, :index_weights, :rank_mode, | ||
| 107 | :max_query_time, :field_weights, :timeout | ||
| 108 | attr_reader :queue | ||
| 109 | |||
| 110 | # Can instantiate with a specific server and port - otherwise it assumes | ||
| 111 | # defaults of localhost and 3312 respectively. All other settings can be | ||
| 112 | # accessed and changed via the attribute accessors. | ||
| 113 | def initialize(server=nil, port=nil) | ||
| 114 | @server = server || "localhost" | ||
| 115 | @port = port || 3312 | ||
| 116 | |||
| 117 | reset | ||
| 118 | |||
| 119 | @queue = [] | ||
| 120 | end | ||
| 121 | |||
| 122 | # Reset attributes and settings to defaults. | ||
| 123 | def reset | ||
| 124 | # defaults | ||
| 125 | @offset = 0 | ||
| 126 | @limit = 20 | ||
| 127 | @max_matches = 1000 | ||
| 128 | @match_mode = :all | ||
| 129 | @sort_mode = :relevance | ||
| 130 | @sort_by = '' | ||
| 131 | @weights = [] | ||
| 132 | @id_range = 0..0 | ||
| 133 | @filters = [] | ||
| 134 | @group_by = '' | ||
| 135 | @group_function = :day | ||
| 136 | @group_clause = '@group desc' | ||
| 137 | @group_distinct = '' | ||
| 138 | @cut_off = 0 | ||
| 139 | @retry_count = 0 | ||
| 140 | @retry_delay = 0 | ||
| 141 | @anchor = {} | ||
| 142 | # string keys are index names, integer values are weightings | ||
| 143 | @index_weights = {} | ||
| 144 | @rank_mode = :proximity_bm25 | ||
| 145 | @max_query_time = 0 | ||
| 146 | # string keys are field names, integer values are weightings | ||
| 147 | @field_weights = {} | ||
| 148 | @timeout = 0 | ||
| 149 | end | ||
| 150 | |||
| 151 | # Set the geo-anchor point - with the names of the attributes that contain | ||
| 152 | # the latitude and longitude (in radians), and the reference position. | ||
| 153 | # Note that for geocoding to work properly, you must also set | ||
| 154 | # match_mode to :extended. To sort results by distance, you will | ||
| 155 | # need to set sort_mode to '@geodist asc' for example. Sphinx | ||
| 156 | # expects latitude and longitude to be returned from you SQL source | ||
| 157 | # in radians. | ||
| 158 | # | ||
| 159 | # Example: | ||
| 160 | # client.set_anchor('lat', -0.6591741, 'long', 2.530770) | ||
| 161 | # | ||
| 162 | def set_anchor(lat_attr, lat, long_attr, long) | ||
| 163 | @anchor = { | ||
| 164 | :latitude_attribute => lat_attr, | ||
| 165 | :latitude => lat, | ||
| 166 | :longitude_attribute => long_attr, | ||
| 167 | :longitude => long | ||
| 168 | } | ||
| 169 | end | ||
| 170 | |||
| 171 | # Append a query to the queue. This uses the same parameters as the query | ||
| 172 | # method. | ||
| 173 | def append_query(search, index = '*', comments = '') | ||
| 174 | @queue << query_message(search, index, comments) | ||
| 175 | end | ||
| 176 | |||
| 177 | # Run all the queries currently in the queue. This will return an array of | ||
| 178 | # results hashes. | ||
| 179 | def run | ||
| 180 | response = Response.new request(:search, @queue) | ||
| 181 | |||
| 182 | results = @queue.collect do | ||
| 183 | result = { | ||
| 184 | :matches => [], | ||
| 185 | :fields => [], | ||
| 186 | :attributes => {}, | ||
| 187 | :attribute_names => [], | ||
| 188 | :words => {} | ||
| 189 | } | ||
| 190 | |||
| 191 | result[:status] = response.next_int | ||
| 192 | case result[:status] | ||
| 193 | when Statuses[:warning] | ||
| 194 | result[:warning] = response.next | ||
| 195 | when Statuses[:error] | ||
| 196 | result[:error] = response.next | ||
| 197 | next result | ||
| 198 | end | ||
| 199 | |||
| 200 | result[:fields] = response.next_array | ||
| 201 | |||
| 202 | attributes = response.next_int | ||
| 203 | for i in 0...attributes | ||
| 204 | attribute_name = response.next | ||
| 205 | type = response.next_int | ||
| 206 | |||
| 207 | result[:attributes][attribute_name] = type | ||
| 208 | result[:attribute_names] << attribute_name | ||
| 209 | end | ||
| 210 | |||
| 211 | matches = response.next_int | ||
| 212 | is_64_bit = response.next_int | ||
| 213 | for i in 0...matches | ||
| 214 | doc = is_64_bit > 0 ? response.next_64bit_int : response.next_int | ||
| 215 | weight = response.next_int | ||
| 216 | |||
| 217 | result[:matches] << {:doc => doc, :weight => weight, :index => i, :attributes => {}} | ||
| 218 | result[:attribute_names].each do |attr| | ||
| 219 | result[:matches].last[:attributes][attr] = attribute_from_type( | ||
| 220 | result[:attributes][attr], response | ||
| 221 | ) | ||
| 222 | end | ||
| 223 | end | ||
| 224 | |||
| 225 | result[:total] = response.next_int.to_i || 0 | ||
| 226 | result[:total_found] = response.next_int.to_i || 0 | ||
| 227 | result[:time] = ('%.3f' % (response.next_int / 1000.0)).to_f || 0.0 | ||
| 228 | |||
| 229 | words = response.next_int | ||
| 230 | for i in 0...words | ||
| 231 | word = response.next | ||
| 232 | docs = response.next_int | ||
| 233 | hits = response.next_int | ||
| 234 | result[:words][word] = {:docs => docs, :hits => hits} | ||
| 235 | end | ||
| 236 | |||
| 237 | result | ||
| 238 | end | ||
| 239 | |||
| 240 | @queue.clear | ||
| 241 | results | ||
| 242 | end | ||
| 243 | |||
| 244 | # Query the Sphinx daemon - defaulting to all indexes, but you can specify | ||
| 245 | # a specific one if you wish. The search parameter should be a string | ||
| 246 | # following Sphinx's expectations. | ||
| 247 | # | ||
| 248 | # The object returned from this method is a hash with the following keys: | ||
| 249 | # | ||
| 250 | # * :matches | ||
| 251 | # * :fields | ||
| 252 | # * :attributes | ||
| 253 | # * :attribute_names | ||
| 254 | # * :words | ||
| 255 | # * :total | ||
| 256 | # * :total_found | ||
| 257 | # * :time | ||
| 258 | # * :status | ||
| 259 | # * :warning (if appropriate) | ||
| 260 | # * :error (if appropriate) | ||
| 261 | # | ||
| 262 | # The key <tt>:matches</tt> returns an array of hashes - the actual search | ||
| 263 | # results. Each hash has the document id (<tt>:doc</tt>), the result | ||
| 264 | # weighting (<tt>:weight</tt>), and a hash of the attributes for the | ||
| 265 | # document (<tt>:attributes</tt>). | ||
| 266 | # | ||
| 267 | # The <tt>:fields</tt> and <tt>:attribute_names</tt> keys return list of | ||
| 268 | # fields and attributes for the documents. The key <tt>:attributes</tt> | ||
| 269 | # will return a hash of attribute name and type pairs, and <tt>:words</tt> | ||
| 270 | # returns a hash of hashes representing the words from the search, with the | ||
| 271 | # number of documents and hits for each, along the lines of: | ||
| 272 | # | ||
| 273 | # results[:words]["Pat"] #=> {:docs => 12, :hits => 15} | ||
| 274 | # | ||
| 275 | # <tt>:total</tt>, <tt>:total_found</tt> and <tt>:time</tt> return the | ||
| 276 | # number of matches available, the total number of matches (which may be | ||
| 277 | # greater than the maximum available, depending on the number of matches | ||
| 278 | # and your sphinx configuration), and the time in milliseconds that the | ||
| 279 | # query took to run. | ||
| 280 | # | ||
| 281 | # <tt>:status</tt> is the error code for the query - and if there was a | ||
| 282 | # related warning, it will be under the <tt>:warning</tt> key. Fatal errors | ||
| 283 | # will be described under <tt>:error</tt>. | ||
| 284 | # | ||
| 285 | def query(search, index = '*', comments = '') | ||
| 286 | @queue << query_message(search, index, comments) | ||
| 287 | self.run.first | ||
| 288 | end | ||
| 289 | |||
| 290 | # Build excerpts from search terms (the +words+) and the text of documents. Excerpts are bodies of text that have the +words+ highlighted. | ||
| 291 | # They may also be abbreviated to fit within a word limit. | ||
| 292 | # | ||
| 293 | # As part of the options hash, you will need to | ||
| 294 | # define: | ||
| 295 | # * :docs | ||
| 296 | # * :words | ||
| 297 | # * :index | ||
| 298 | # | ||
| 299 | # Optional settings include: | ||
| 300 | # * :before_match (defaults to <span class="match">) | ||
| 301 | # * :after_match (defaults to </span>) | ||
| 302 | # * :chunk_separator (defaults to ' … ' - which is an HTML ellipsis) | ||
| 303 | # * :limit (defaults to 256) | ||
| 304 | # * :around (defaults to 5) | ||
| 305 | # * :exact_phrase (defaults to false) | ||
| 306 | # * :single_passage (defaults to false) | ||
| 307 | # | ||
| 308 | # The defaults differ from the official PHP client, as I've opted for | ||
| 309 | # semantic HTML markup. | ||
| 310 | # | ||
| 311 | # Example: | ||
| 312 | # | ||
| 313 | # client.excerpts(:docs => ["Pat Allan, Pat Cash"], :words => 'Pat', :index => 'pats') | ||
| 314 | # #=> ["<span class=\"match\">Pat</span> Allan, <span class=\"match\">Pat</span> Cash"] | ||
| 315 | # | ||
| 316 | # lorem_lipsum = "Lorem ipsum dolor..." | ||
| 317 | # | ||
| 318 | # client.excerpts(:docs => ["Pat Allan, #{lorem_lipsum} Pat Cash"], :words => 'Pat', :index => 'pats') | ||
| 319 | # #=> ["<span class=\"match\">Pat</span> Allan, Lorem ipsum dolor sit amet, consectetur adipisicing | ||
| 320 | # elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua … . Excepteur | ||
| 321 | # sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est | ||
| 322 | # laborum. <span class=\"match\">Pat</span> Cash"] | ||
| 323 | # | ||
| 324 | # Workflow: | ||
| 325 | # | ||
| 326 | # Excerpt creation is completely isolated from searching the index. The nominated index is only used to | ||
| 327 | # discover encoding and charset information. | ||
| 328 | # | ||
| 329 | # Therefore, the workflow goes: | ||
| 330 | # | ||
| 331 | # 1. Do the sphinx query. | ||
| 332 | # 2. Fetch the documents found by sphinx from their repositories. | ||
| 333 | # 3. Pass the documents' text to +excerpts+ for marking up of matched terms. | ||
| 334 | # | ||
| 335 | def excerpts(options = {}) | ||
| 336 | options[:index] ||= '*' | ||
| 337 | options[:before_match] ||= '<span class="match">' | ||
| 338 | options[:after_match] ||= '</span>' | ||
| 339 | options[:chunk_separator] ||= ' … ' # ellipsis | ||
| 340 | options[:limit] ||= 256 | ||
| 341 | options[:around] ||= 5 | ||
| 342 | options[:exact_phrase] ||= false | ||
| 343 | options[:single_passage] ||= false | ||
| 344 | |||
| 345 | response = Response.new request(:excerpt, excerpts_message(options)) | ||
| 346 | |||
| 347 | options[:docs].collect { response.next } | ||
| 348 | end | ||
| 349 | |||
| 350 | # Update attributes - first parameter is the relevant index, second is an | ||
| 351 | # array of attributes to be updated, and the third is a hash, where the | ||
| 352 | # keys are the document ids, and the values are arrays with the attribute | ||
| 353 | # values - in the same order as the second parameter. | ||
| 354 | # | ||
| 355 | # Example: | ||
| 356 | # | ||
| 357 | # client.update('people', ['birthday'], {1 => [Time.at(1982, 20, 8).to_i]}) | ||
| 358 | # | ||
| 359 | def update(index, attributes, values_by_doc) | ||
| 360 | response = Response.new request( | ||
| 361 | :update, | ||
| 362 | update_message(index, attributes, values_by_doc) | ||
| 363 | ) | ||
| 364 | |||
| 365 | response.next_int | ||
| 366 | end | ||
| 367 | |||
| 368 | # Generates a keyword list for a given query. Each keyword is represented | ||
| 369 | # by a hash, with keys :tokenised and :normalised. If return_hits is set to | ||
| 370 | # true it will also report on the number of hits and documents for each | ||
| 371 | # keyword (see :hits and :docs keys respectively). | ||
| 372 | def keywords(query, index, return_hits = false) | ||
| 373 | response = Response.new request( | ||
| 374 | :keywords, | ||
| 375 | keywords_message(query, index, return_hits) | ||
| 376 | ) | ||
| 377 | |||
| 378 | (0...response.next_int).collect do | ||
| 379 | hash = {} | ||
| 380 | hash[:tokenised] = response.next | ||
| 381 | hash[:normalised] = response.next | ||
| 382 | |||
| 383 | if return_hits | ||
| 384 | hash[:docs] = response.next_int | ||
| 385 | hash[:hits] = response.next_int | ||
| 386 | end | ||
| 387 | |||
| 388 | hash | ||
| 389 | end | ||
| 390 | end | ||
| 391 | |||
| 392 | private | ||
| 393 | |||
| 394 | # Connects to the Sphinx daemon, and yields a socket to use. The socket is | ||
| 395 | # closed at the end of the block. | ||
| 396 | def connect(&block) | ||
| 397 | socket = nil | ||
| 398 | if @timeout == 0 | ||
| 399 | socket = initialise_connection | ||
| 400 | else | ||
| 401 | begin | ||
| 402 | Timeout.timeout(@timeout) { socket = initialise_connection } | ||
| 403 | rescue Timeout::Error | ||
| 404 | raise Riddle::ConnectionError, | ||
| 405 | "Connection to #{@server} on #{@port} timed out after #{@timeout} seconds" | ||
| 406 | end | ||
| 407 | end | ||
| 408 | |||
| 409 | begin | ||
| 410 | yield socket | ||
| 411 | ensure | ||
| 412 | socket.close | ||
| 413 | end | ||
| 414 | end | ||
| 415 | |||
| 416 | def initialise_connection | ||
| 417 | socket = TCPSocket.new @server, @port | ||
| 418 | |||
| 419 | # Checking version | ||
| 420 | version = socket.recv(4).unpack('N*').first | ||
| 421 | if version < 1 | ||
| 422 | socket.close | ||
| 423 | raise VersionError, "Can only connect to searchd version 1.0 or better, not version #{version}" | ||
| 424 | end | ||
| 425 | |||
| 426 | # Send version | ||
| 427 | socket.send [1].pack('N'), 0 | ||
| 428 | |||
| 429 | socket | ||
| 430 | end | ||
| 431 | |||
| 432 | # Send a collection of messages, for a command type (eg, search, excerpts, | ||
| 433 | # update), to the Sphinx daemon. | ||
| 434 | def request(command, messages) | ||
| 435 | response = "" | ||
| 436 | status = -1 | ||
| 437 | version = 0 | ||
| 438 | length = 0 | ||
| 439 | message = Array(messages).join("") | ||
| 440 | |||
| 441 | connect do |socket| | ||
| 442 | case command | ||
| 443 | when :search | ||
| 444 | # Message length is +4 to account for the following count value for | ||
| 445 | # the number of messages (well, that's what I'm assuming). | ||
| 446 | socket.send [ | ||
| 447 | Commands[command], Versions[command], | ||
| 448 | 4+message.length, messages.length | ||
| 449 | ].pack("nnNN") + message, 0 | ||
| 450 | else | ||
| 451 | socket.send [ | ||
| 452 | Commands[command], Versions[command], message.length | ||
| 453 | ].pack("nnN") + message, 0 | ||
| 454 | end | ||
| 455 | |||
| 456 | header = socket.recv(8) | ||
| 457 | status, version, length = header.unpack('n2N') | ||
| 458 | |||
| 459 | while response.length < (length || 0) | ||
| 460 | part = socket.recv(length - response.length) | ||
| 461 | response << part if part | ||
| 462 | end | ||
| 463 | end | ||
| 464 | |||
| 465 | if response.empty? || response.length != length | ||
| 466 | raise ResponseError, "No response from searchd (status: #{status}, version: #{version})" | ||
| 467 | end | ||
| 468 | |||
| 469 | case status | ||
| 470 | when Statuses[:ok] | ||
| 471 | if version < Versions[command] | ||
| 472 | puts format("searchd command v.%d.%d older than client (v.%d.%d)", | ||
| 473 | version >> 8, version & 0xff, | ||
| 474 | Versions[command] >> 8, Versions[command] & 0xff) | ||
| 475 | end | ||
| 476 | response | ||
| 477 | when Statuses[:warning] | ||
| 478 | length = response[0, 4].unpack('N*').first | ||
| 479 | puts response[4, length] | ||
| 480 | response[4 + length, response.length - 4 - length] | ||
| 481 | when Statuses[:error], Statuses[:retry] | ||
| 482 | raise ResponseError, "searchd error (status: #{status}): #{response[4, response.length - 4]}" | ||
| 483 | else | ||
| 484 | raise ResponseError, "Unknown searchd error (status: #{status})" | ||
| 485 | end | ||
| 486 | end | ||
| 487 | |||
| 488 | # Generation of the message to send to Sphinx for a search. | ||
| 489 | def query_message(search, index, comments = '') | ||
| 490 | message = Message.new | ||
| 491 | |||
| 492 | # Mode, Limits, Sort Mode | ||
| 493 | message.append_ints @offset, @limit, MatchModes[@match_mode], | ||
| 494 | RankModes[@rank_mode], SortModes[@sort_mode] | ||
| 495 | message.append_string @sort_by | ||
| 496 | |||
| 497 | # Query | ||
| 498 | message.append_string search | ||
| 499 | |||
| 500 | # Weights | ||
| 501 | message.append_int @weights.length | ||
| 502 | message.append_ints *@weights | ||
| 503 | |||
| 504 | # Index | ||
| 505 | message.append_string index | ||
| 506 | |||
| 507 | # ID Range | ||
| 508 | message.append_int 1 | ||
| 509 | message.append_64bit_ints @id_range.first, @id_range.last | ||
| 510 | |||
| 511 | # Filters | ||
| 512 | message.append_int @filters.length | ||
| 513 | @filters.each { |filter| message.append filter.query_message } | ||
| 514 | |||
| 515 | # Grouping | ||
| 516 | message.append_int GroupFunctions[@group_function] | ||
| 517 | message.append_string @group_by | ||
| 518 | message.append_int @max_matches | ||
| 519 | message.append_string @group_clause | ||
| 520 | message.append_ints @cut_off, @retry_count, @retry_delay | ||
| 521 | message.append_string @group_distinct | ||
| 522 | |||
| 523 | # Anchor Point | ||
| 524 | if @anchor.empty? | ||
| 525 | message.append_int 0 | ||
| 526 | else | ||
| 527 | message.append_int 1 | ||
| 528 | message.append_string @anchor[:latitude_attribute] | ||
| 529 | message.append_string @anchor[:longitude_attribute] | ||
| 530 | message.append_floats @anchor[:latitude], @anchor[:longitude] | ||
| 531 | end | ||
| 532 | |||
| 533 | # Per Index Weights | ||
| 534 | message.append_int @index_weights.length | ||
| 535 | @index_weights.each do |key,val| | ||
| 536 | message.append_string key.to_s | ||
| 537 | message.append_int val | ||
| 538 | end | ||
| 539 | |||
| 540 | # Max Query Time | ||
| 541 | message.append_int @max_query_time | ||
| 542 | |||
| 543 | # Per Field Weights | ||
| 544 | message.append_int @field_weights.length | ||
| 545 | @field_weights.each do |key,val| | ||
| 546 | message.append_string key.to_s | ||
| 547 | message.append_int val | ||
| 548 | end | ||
| 549 | |||
| 550 | message.append_string comments | ||
| 551 | |||
| 552 | message.to_s | ||
| 553 | end | ||
| 554 | |||
| 555 | # Generation of the message to send to Sphinx for an excerpts request. | ||
| 556 | def excerpts_message(options) | ||
| 557 | message = Message.new | ||
| 558 | |||
| 559 | flags = 1 | ||
| 560 | flags |= 2 if options[:exact_phrase] | ||
| 561 | flags |= 4 if options[:single_passage] | ||
| 562 | flags |= 8 if options[:use_boundaries] | ||
| 563 | flags |= 16 if options[:weight_order] | ||
| 564 | |||
| 565 | message.append [0, flags].pack('N2') # 0 = mode | ||
| 566 | message.append_string options[:index] | ||
| 567 | message.append_string options[:words] | ||
| 568 | |||
| 569 | # options | ||
| 570 | message.append_string options[:before_match] | ||
| 571 | message.append_string options[:after_match] | ||
| 572 | message.append_string options[:chunk_separator] | ||
| 573 | message.append_ints options[:limit], options[:around] | ||
| 574 | |||
| 575 | message.append_array options[:docs] | ||
| 576 | |||
| 577 | message.to_s | ||
| 578 | end | ||
| 579 | |||
| 580 | # Generation of the message to send to Sphinx to update attributes of a | ||
| 581 | # document. | ||
| 582 | def update_message(index, attributes, values_by_doc) | ||
| 583 | message = Message.new | ||
| 584 | |||
| 585 | message.append_string index | ||
| 586 | message.append_array attributes | ||
| 587 | |||
| 588 | message.append_int values_by_doc.length | ||
| 589 | values_by_doc.each do |key,values| | ||
| 590 | message.append_64bit_int key # document ID | ||
| 591 | message.append_ints *values # array of new values (integers) | ||
| 592 | end | ||
| 593 | |||
| 594 | message.to_s | ||
| 595 | end | ||
| 596 | |||
| 597 | # Generates the simple message to send to the daemon for a keywords request. | ||
| 598 | def keywords_message(query, index, return_hits) | ||
| 599 | message = Message.new | ||
| 600 | |||
| 601 | message.append_string query | ||
| 602 | message.append_string index | ||
| 603 | message.append_int return_hits ? 1 : 0 | ||
| 604 | |||
| 605 | message.to_s | ||
| 606 | end | ||
| 607 | |||
| 608 | def attribute_from_type(type, response) | ||
| 609 | type -= AttributeTypes[:multi] if is_multi = type > AttributeTypes[:multi] | ||
| 610 | |||
| 611 | case type | ||
| 612 | when AttributeTypes[:float] | ||
| 613 | is_multi ? response.next_float_array : response.next_float | ||
| 614 | else | ||
| 615 | is_multi ? response.next_int_array : response.next_int | ||
| 616 | end | ||
| 617 | end | ||
| 618 | end | ||
| 619 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/filter.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/filter.rb new file mode 100644 index 0000000..65aa26a --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/filter.rb | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | module Riddle | ||
| 2 | class Client | ||
| 3 | # Used for querying Sphinx. | ||
| 4 | class Filter | ||
| 5 | attr_accessor :attribute, :values, :exclude | ||
| 6 | |||
| 7 | # Attribute name, values (which can be an array or a range), and whether | ||
| 8 | # the filter should be exclusive. | ||
| 9 | def initialize(attribute, values, exclude=false) | ||
| 10 | @attribute, @values, @exclude = attribute, values, exclude | ||
| 11 | end | ||
| 12 | |||
| 13 | def exclude? | ||
| 14 | self.exclude | ||
| 15 | end | ||
| 16 | |||
| 17 | # Returns the message for this filter to send to the Sphinx service | ||
| 18 | def query_message | ||
| 19 | message = Message.new | ||
| 20 | |||
| 21 | message.append_string self.attribute.to_s | ||
| 22 | case self.values | ||
| 23 | when Range | ||
| 24 | if self.values.first.is_a?(Float) && self.values.last.is_a?(Float) | ||
| 25 | message.append_int FilterTypes[:float_range] | ||
| 26 | message.append_floats self.values.first, self.values.last | ||
| 27 | else | ||
| 28 | message.append_int FilterTypes[:range] | ||
| 29 | message.append_ints self.values.first, self.values.last | ||
| 30 | end | ||
| 31 | when Array | ||
| 32 | message.append_int FilterTypes[:values] | ||
| 33 | message.append_int self.values.length | ||
| 34 | # using to_f is a hack from the php client - to workaround 32bit | ||
| 35 | # signed ints on x32 platforms | ||
| 36 | message.append_ints *self.values.collect { |val| | ||
| 37 | case val | ||
| 38 | when TrueClass | ||
| 39 | 1.0 | ||
| 40 | when FalseClass | ||
| 41 | 0.0 | ||
| 42 | else | ||
| 43 | val.to_f | ||
| 44 | end | ||
| 45 | } | ||
| 46 | end | ||
| 47 | message.append_int self.exclude? ? 1 : 0 | ||
| 48 | |||
| 49 | message.to_s | ||
| 50 | end | ||
| 51 | end | ||
| 52 | end | ||
| 53 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/message.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/message.rb new file mode 100644 index 0000000..4b29ad9 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/message.rb | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | module Riddle | ||
| 2 | class Client | ||
| 3 | # This class takes care of the translation of ints, strings and arrays to | ||
| 4 | # the format required by the Sphinx service. | ||
| 5 | class Message | ||
| 6 | def initialize | ||
| 7 | @message = "" | ||
| 8 | @size_method = @message.respond_to?(:bytesize) ? :bytesize : :length | ||
| 9 | end | ||
| 10 | |||
| 11 | # Append raw data (only use if you know what you're doing) | ||
| 12 | def append(*args) | ||
| 13 | return if args.length == 0 | ||
| 14 | |||
| 15 | args.each { |arg| @message << arg } | ||
| 16 | end | ||
| 17 | |||
| 18 | # Append a string's length, then the string itself | ||
| 19 | def append_string(str) | ||
| 20 | @message << [str.send(@size_method)].pack('N') + str | ||
| 21 | end | ||
| 22 | |||
| 23 | # Append an integer | ||
| 24 | def append_int(int) | ||
| 25 | @message << [int].pack('N') | ||
| 26 | end | ||
| 27 | |||
| 28 | def append_64bit_int(int) | ||
| 29 | @message << [int >> 32, int & 0xFFFFFFFF].pack('NN') | ||
| 30 | end | ||
| 31 | |||
| 32 | # Append a float | ||
| 33 | def append_float(float) | ||
| 34 | @message << [float].pack('f').unpack('L*').pack("N") | ||
| 35 | end | ||
| 36 | |||
| 37 | # Append multiple integers | ||
| 38 | def append_ints(*ints) | ||
| 39 | ints.each { |int| append_int(int) } | ||
| 40 | end | ||
| 41 | |||
| 42 | def append_64bit_ints(*ints) | ||
| 43 | ints.each { |int| append_64bit_int(int) } | ||
| 44 | end | ||
| 45 | |||
| 46 | # Append multiple floats | ||
| 47 | def append_floats(*floats) | ||
| 48 | floats.each { |float| append_float(float) } | ||
| 49 | end | ||
| 50 | |||
| 51 | # Append an array of strings - first appends the length of the array, | ||
| 52 | # then each item's length and value. | ||
| 53 | def append_array(array) | ||
| 54 | append_int(array.length) | ||
| 55 | |||
| 56 | array.each { |item| append_string(item) } | ||
| 57 | end | ||
| 58 | |||
| 59 | # Returns the entire message | ||
| 60 | def to_s | ||
| 61 | @message | ||
| 62 | end | ||
| 63 | end | ||
| 64 | end | ||
| 65 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/response.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/response.rb new file mode 100644 index 0000000..18423e6 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/client/response.rb | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | module Riddle | ||
| 2 | class Client | ||
| 3 | # Used to interrogate responses from the Sphinx daemon. Keep in mind none | ||
| 4 | # of the methods here check whether the data they're grabbing are what the | ||
| 5 | # user expects - it just assumes the user knows what the data stream is | ||
| 6 | # made up of. | ||
| 7 | class Response | ||
| 8 | # Create with the data to interpret | ||
| 9 | def initialize(str) | ||
| 10 | @str = str | ||
| 11 | @marker = 0 | ||
| 12 | end | ||
| 13 | |||
| 14 | # Return the next string value in the stream | ||
| 15 | def next | ||
| 16 | len = next_int | ||
| 17 | result = @str[@marker, len] | ||
| 18 | @marker += len | ||
| 19 | |||
| 20 | return result | ||
| 21 | end | ||
| 22 | |||
| 23 | # Return the next integer value from the stream | ||
| 24 | def next_int | ||
| 25 | int = @str[@marker, 4].unpack('N*').first | ||
| 26 | @marker += 4 | ||
| 27 | |||
| 28 | return int | ||
| 29 | end | ||
| 30 | |||
| 31 | def next_64bit_int | ||
| 32 | high, low = @str[@marker, 8].unpack('N*N*')[0..1] | ||
| 33 | @marker += 8 | ||
| 34 | |||
| 35 | return (high << 32) + low | ||
| 36 | end | ||
| 37 | |||
| 38 | # Return the next float value from the stream | ||
| 39 | def next_float | ||
| 40 | float = @str[@marker, 4].unpack('N*').pack('L').unpack('f*').first | ||
| 41 | @marker += 4 | ||
| 42 | |||
| 43 | return float | ||
| 44 | end | ||
| 45 | |||
| 46 | # Returns an array of string items | ||
| 47 | def next_array | ||
| 48 | count = next_int | ||
| 49 | items = [] | ||
| 50 | for i in 0...count | ||
| 51 | items << self.next | ||
| 52 | end | ||
| 53 | |||
| 54 | return items | ||
| 55 | end | ||
| 56 | |||
| 57 | # Returns an array of int items | ||
| 58 | def next_int_array | ||
| 59 | count = next_int | ||
| 60 | items = [] | ||
| 61 | for i in 0...count | ||
| 62 | items << self.next_int | ||
| 63 | end | ||
| 64 | |||
| 65 | return items | ||
| 66 | end | ||
| 67 | |||
| 68 | def next_float_array | ||
| 69 | count = next_int | ||
| 70 | items = [] | ||
| 71 | for i in 0...count | ||
| 72 | items << self.next_float | ||
| 73 | end | ||
| 74 | |||
| 75 | return items | ||
| 76 | end | ||
| 77 | |||
| 78 | # Returns the length of the streamed data | ||
| 79 | def length | ||
| 80 | @str.length | ||
| 81 | end | ||
| 82 | end | ||
| 83 | end | ||
| 84 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration.rb new file mode 100644 index 0000000..666bca6 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration.rb | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | require 'riddle/configuration/section' | ||
| 2 | |||
| 3 | require 'riddle/configuration/distributed_index' | ||
| 4 | require 'riddle/configuration/index' | ||
| 5 | require 'riddle/configuration/indexer' | ||
| 6 | require 'riddle/configuration/remote_index' | ||
| 7 | require 'riddle/configuration/searchd' | ||
| 8 | require 'riddle/configuration/source' | ||
| 9 | require 'riddle/configuration/sql_source' | ||
| 10 | require 'riddle/configuration/xml_source' | ||
| 11 | |||
| 12 | module Riddle | ||
| 13 | class Configuration | ||
| 14 | class ConfigurationError < StandardError #:nodoc: | ||
| 15 | end | ||
| 16 | |||
| 17 | attr_reader :indexes, :searchd | ||
| 18 | attr_accessor :indexer | ||
| 19 | |||
| 20 | def initialize | ||
| 21 | @indexer = Riddle::Configuration::Indexer.new | ||
| 22 | @searchd = Riddle::Configuration::Searchd.new | ||
| 23 | @indexes = [] | ||
| 24 | end | ||
| 25 | |||
| 26 | def render | ||
| 27 | ( | ||
| 28 | [@indexer.render, @searchd.render] + | ||
| 29 | @indexes.collect { |index| index.render } | ||
| 30 | ).join("\n") | ||
| 31 | end | ||
| 32 | end | ||
| 33 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/distributed_index.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/distributed_index.rb new file mode 100644 index 0000000..9c7ef86 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/distributed_index.rb | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class DistributedIndex < Riddle::Configuration::Section | ||
| 4 | self.settings = [:type, :local, :agent, :agent_connect_timeout, | ||
| 5 | :agent_query_timeout] | ||
| 6 | |||
| 7 | attr_accessor :name, :local_indexes, :remote_indexes, | ||
| 8 | :agent_connect_timeout, :agent_query_timeout | ||
| 9 | |||
| 10 | def initialize(name) | ||
| 11 | @name = name | ||
| 12 | @local_indexes = [] | ||
| 13 | @remote_indexes = [] | ||
| 14 | end | ||
| 15 | |||
| 16 | def type | ||
| 17 | "distributed" | ||
| 18 | end | ||
| 19 | |||
| 20 | def local | ||
| 21 | self.local_indexes | ||
| 22 | end | ||
| 23 | |||
| 24 | def agent | ||
| 25 | agents = remote_indexes.collect { |index| index.remote }.uniq | ||
| 26 | agents.collect { |agent| | ||
| 27 | agent + ":" + remote_indexes.select { |index| | ||
| 28 | index.remote == agent | ||
| 29 | }.collect { |index| index.name }.join(",") | ||
| 30 | } | ||
| 31 | end | ||
| 32 | |||
| 33 | def render | ||
| 34 | raise ConfigurationError unless valid? | ||
| 35 | |||
| 36 | ( | ||
| 37 | ["index #{name}", "{"] + | ||
| 38 | settings_body + | ||
| 39 | ["}", ""] | ||
| 40 | ).join("\n") | ||
| 41 | end | ||
| 42 | |||
| 43 | def valid? | ||
| 44 | @local_indexes.length > 0 || @remote_indexes.length > 0 | ||
| 45 | end | ||
| 46 | end | ||
| 47 | end | ||
| 48 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/index.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/index.rb new file mode 100644 index 0000000..4cd8a03 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/index.rb | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class Index < Riddle::Configuration::Section | ||
| 4 | self.settings = [:source, :path, :docinfo, :mlock, :morphology, | ||
| 5 | :stopwords, :wordforms, :exceptions, :min_word_len, :charset_type, | ||
| 6 | :charset_table, :ignore_chars, :min_prefix_len, :min_infix_len, | ||
| 7 | :prefix_fields, :infix_fields, :enable_star, :ngram_len, :ngram_chars, | ||
| 8 | :phrase_boundary, :phrase_boundary_step, :html_strip, | ||
| 9 | :html_index_attrs, :html_remove_elements, :preopen] | ||
| 10 | |||
| 11 | attr_accessor :name, :parent, :sources, :path, :docinfo, :mlock, | ||
| 12 | :morphologies, :stopword_files, :wordform_files, :exception_files, | ||
| 13 | :min_word_len, :charset_type, :charset_table, :ignore_characters, | ||
| 14 | :min_prefix_len, :min_infix_len, :prefix_field_names, | ||
| 15 | :infix_field_names, :enable_star, :ngram_len, :ngram_characters, | ||
| 16 | :phrase_boundaries, :phrase_boundary_step, :html_strip, | ||
| 17 | :html_index_attrs, :html_remove_element_tags, :preopen | ||
| 18 | |||
| 19 | def initialize(name, *sources) | ||
| 20 | @name = name | ||
| 21 | @sources = sources | ||
| 22 | @morphologies = [] | ||
| 23 | @stopword_files = [] | ||
| 24 | @wordform_files = [] | ||
| 25 | @exception_files = [] | ||
| 26 | @ignore_characters = [] | ||
| 27 | @prefix_field_names = [] | ||
| 28 | @infix_field_names = [] | ||
| 29 | @ngram_characters = [] | ||
| 30 | @phrase_boundaries = [] | ||
| 31 | @html_remove_element_tags = [] | ||
| 32 | end | ||
| 33 | |||
| 34 | def source | ||
| 35 | @sources.collect { |s| s.name } | ||
| 36 | end | ||
| 37 | |||
| 38 | def morphology | ||
| 39 | nil_join @morphologies, ", " | ||
| 40 | end | ||
| 41 | |||
| 42 | def morphology=(morphology) | ||
| 43 | @morphologies = nil_split morphology, /,\s?/ | ||
| 44 | end | ||
| 45 | |||
| 46 | def stopwords | ||
| 47 | nil_join @stopword_files, " " | ||
| 48 | end | ||
| 49 | |||
| 50 | def stopwords=(stopwords) | ||
| 51 | @stopword_files = nil_split stopwords, ' ' | ||
| 52 | end | ||
| 53 | |||
| 54 | def wordforms | ||
| 55 | nil_join @wordform_files, " " | ||
| 56 | end | ||
| 57 | |||
| 58 | def wordforms=(wordforms) | ||
| 59 | @wordform_files = nil_split wordforms, ' ' | ||
| 60 | end | ||
| 61 | |||
| 62 | def exceptions | ||
| 63 | nil_join @exception_files, " " | ||
| 64 | end | ||
| 65 | |||
| 66 | def exceptions=(exceptions) | ||
| 67 | @exception_files = nil_split exceptions, ' ' | ||
| 68 | end | ||
| 69 | |||
| 70 | def ignore_chars | ||
| 71 | nil_join @ignore_characters, ", " | ||
| 72 | end | ||
| 73 | |||
| 74 | def ignore_chars=(ignore_chars) | ||
| 75 | @ignore_characters = nil_split ignore_chars, /,\s?/ | ||
| 76 | end | ||
| 77 | |||
| 78 | def prefix_fields | ||
| 79 | nil_join @prefix_field_names, ", " | ||
| 80 | end | ||
| 81 | |||
| 82 | def infix_fields | ||
| 83 | nil_join @infix_field_names, ", " | ||
| 84 | end | ||
| 85 | |||
| 86 | def ngram_chars | ||
| 87 | nil_join @ngram_characters, ", " | ||
| 88 | end | ||
| 89 | |||
| 90 | def ngram_chars=(ngram_chars) | ||
| 91 | @ngram_characters = nil_split ngram_chars, /,\s?/ | ||
| 92 | end | ||
| 93 | |||
| 94 | def phrase_boundary | ||
| 95 | nil_join @phrase_boundaries, ", " | ||
| 96 | end | ||
| 97 | |||
| 98 | def phrase_boundary=(phrase_boundary) | ||
| 99 | @phrase_boundaries = nil_split phrase_boundary, /,\s?/ | ||
| 100 | end | ||
| 101 | |||
| 102 | def html_remove_elements | ||
| 103 | nil_join @html_remove_element_tags, ", " | ||
| 104 | end | ||
| 105 | |||
| 106 | def html_remove_elements=(html_remove_elements) | ||
| 107 | @html_remove_element_tags = nil_split html_remove_elements, /,\s?/ | ||
| 108 | end | ||
| 109 | |||
| 110 | def render | ||
| 111 | raise ConfigurationError, "#{@name} #{@sources.inspect} #{@path} #{@parent}" unless valid? | ||
| 112 | |||
| 113 | inherited_name = "#{name}" | ||
| 114 | inherited_name << " : #{parent}" if parent | ||
| 115 | ( | ||
| 116 | @sources.collect { |s| s.render } + | ||
| 117 | ["index #{inherited_name}", "{"] + | ||
| 118 | settings_body + | ||
| 119 | ["}", ""] | ||
| 120 | ).join("\n") | ||
| 121 | end | ||
| 122 | |||
| 123 | def valid? | ||
| 124 | (!@name.nil?) && (!( @sources.length == 0 || @path.nil? ) || !@parent.nil?) | ||
| 125 | end | ||
| 126 | |||
| 127 | private | ||
| 128 | |||
| 129 | def nil_split(string, pattern) | ||
| 130 | (string || "").split(pattern) | ||
| 131 | end | ||
| 132 | |||
| 133 | def nil_join(array, delimiter) | ||
| 134 | if array.length == 0 | ||
| 135 | nil | ||
| 136 | else | ||
| 137 | array.join(delimiter) | ||
| 138 | end | ||
| 139 | end | ||
| 140 | end | ||
| 141 | end | ||
| 142 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/indexer.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/indexer.rb new file mode 100644 index 0000000..3a88b2b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/indexer.rb | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class Indexer < Riddle::Configuration::Section | ||
| 4 | self.settings = [:mem_limit, :max_iops, :max_iosize] | ||
| 5 | |||
| 6 | attr_accessor *self.settings | ||
| 7 | |||
| 8 | def render | ||
| 9 | raise ConfigurationError unless valid? | ||
| 10 | |||
| 11 | ( | ||
| 12 | ["indexer", "{"] + | ||
| 13 | settings_body + | ||
| 14 | ["}", ""] | ||
| 15 | ).join("\n") | ||
| 16 | end | ||
| 17 | end | ||
| 18 | end | ||
| 19 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/remote_index.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/remote_index.rb new file mode 100644 index 0000000..c9c8323 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/remote_index.rb | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class RemoteIndex | ||
| 4 | attr_accessor :address, :port, :name | ||
| 5 | |||
| 6 | def initialize(address, port, name) | ||
| 7 | @address = address | ||
| 8 | @port = port | ||
| 9 | @name = name | ||
| 10 | end | ||
| 11 | |||
| 12 | def remote | ||
| 13 | "#{address}:#{port}" | ||
| 14 | end | ||
| 15 | end | ||
| 16 | end | ||
| 17 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/searchd.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/searchd.rb new file mode 100644 index 0000000..d113488 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/searchd.rb | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class Searchd < Riddle::Configuration::Section | ||
| 4 | self.settings = [:address, :port, :log, :query_log, :read_timeout, | ||
| 5 | :max_children, :pid_file, :max_matches, :seamless_rotate, | ||
| 6 | :preopen_indexes, :unlink_old] | ||
| 7 | |||
| 8 | attr_accessor *self.settings | ||
| 9 | |||
| 10 | def render | ||
| 11 | raise ConfigurationError unless valid? | ||
| 12 | |||
| 13 | ( | ||
| 14 | ["searchd", "{"] + | ||
| 15 | settings_body + | ||
| 16 | ["}", ""] | ||
| 17 | ).join("\n") | ||
| 18 | end | ||
| 19 | |||
| 20 | def valid? | ||
| 21 | !( @port.nil? || @pid_file.nil? ) | ||
| 22 | end | ||
| 23 | end | ||
| 24 | end | ||
| 25 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/section.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/section.rb new file mode 100644 index 0000000..acd891b --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/section.rb | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class Section | ||
| 4 | class << self | ||
| 5 | attr_accessor :settings | ||
| 6 | end | ||
| 7 | |||
| 8 | settings = [] | ||
| 9 | |||
| 10 | def valid? | ||
| 11 | true | ||
| 12 | end | ||
| 13 | |||
| 14 | private | ||
| 15 | |||
| 16 | def settings_body | ||
| 17 | self.class.settings.select { |setting| | ||
| 18 | !send(setting).nil? | ||
| 19 | }.collect { |setting| | ||
| 20 | if send(setting) == "" | ||
| 21 | conf = " #{setting} = " | ||
| 22 | else | ||
| 23 | conf = setting_to_array(setting).collect { |set| | ||
| 24 | " #{setting} = #{set}" | ||
| 25 | } | ||
| 26 | end | ||
| 27 | conf.length == 0 ? nil : conf | ||
| 28 | }.flatten.compact | ||
| 29 | end | ||
| 30 | |||
| 31 | def setting_to_array(setting) | ||
| 32 | value = send(setting) | ||
| 33 | value.is_a?(Array) ? value : [value] | ||
| 34 | end | ||
| 35 | end | ||
| 36 | end | ||
| 37 | end | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/source.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/source.rb new file mode 100644 index 0000000..15e75f9 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/source.rb | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class Source < Riddle::Configuration::Section | ||
| 4 | attr_accessor :name, :parent, :type | ||
| 5 | |||
| 6 | def render | ||
| 7 | raise ConfigurationError unless valid? | ||
| 8 | |||
| 9 | inherited_name = "#{name}" | ||
| 10 | inherited_name << " : #{parent}" if parent | ||
| 11 | ( | ||
| 12 | ["source #{inherited_name}", "{"] + | ||
| 13 | settings_body + | ||
| 14 | ["}", ""] | ||
| 15 | ).join("\n") | ||
| 16 | end | ||
| 17 | |||
| 18 | def valid? | ||
| 19 | !( @name.nil? || @type.nil? ) | ||
| 20 | end | ||
| 21 | end | ||
| 22 | end | ||
| 23 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/sql_source.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/sql_source.rb new file mode 100644 index 0000000..8521c97 --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/sql_source.rb | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class SQLSource < Riddle::Configuration::Source | ||
| 4 | self.settings = [:type, :sql_host, :sql_user, :sql_pass, :sql_db, | ||
| 5 | :sql_port, :sql_sock, :mysql_connect_flags, :sql_query_pre, :sql_query, | ||
| 6 | :sql_query_range, :sql_range_step, :sql_attr_uint, :sql_attr_bool, | ||
| 7 | :sql_attr_timestamp, :sql_attr_str2ordinal, :sql_attr_float, | ||
| 8 | :sql_attr_multi, :sql_query_post, :sql_query_post_index, | ||
| 9 | :sql_ranged_throttle, :sql_query_info] | ||
| 10 | |||
| 11 | attr_accessor *self.settings | ||
| 12 | |||
| 13 | def initialize(name, type) | ||
| 14 | @name = name | ||
| 15 | @type = type | ||
| 16 | |||
| 17 | @sql_query_pre = [] | ||
| 18 | @sql_attr_uint = [] | ||
| 19 | @sql_attr_bool = [] | ||
| 20 | @sql_attr_timestamp = [] | ||
| 21 | @sql_attr_str2ordinal = [] | ||
| 22 | @sql_attr_float = [] | ||
| 23 | @sql_attr_multi = [] | ||
| 24 | @sql_query_post = [] | ||
| 25 | @sql_query_post_index = [] | ||
| 26 | end | ||
| 27 | |||
| 28 | def valid? | ||
| 29 | super && (!( @sql_host.nil? || @sql_user.nil? || @sql_db.nil? || | ||
| 30 | @sql_query.nil? ) || !@parent.nil?) | ||
| 31 | end | ||
| 32 | end | ||
| 33 | end | ||
| 34 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/xml_source.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/xml_source.rb new file mode 100644 index 0000000..0c3d3ec --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/configuration/xml_source.rb | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | module Riddle | ||
| 2 | class Configuration | ||
| 3 | class XMLSource < Riddle::Configuration::Source | ||
| 4 | self.settings = [:type, :xmlpipe_command, :xmlpipe_field, | ||
| 5 | :xmlpipe_attr_uint, :xmlpipe_attr_bool, :xmlpipe_attr_timestamp, | ||
| 6 | :xmlpipe_attr_str2ordinal, :xmlpipe_attr_float, :xmlpipe_attr_multi] | ||
| 7 | |||
| 8 | attr_accessor *self.settings | ||
| 9 | |||
| 10 | def initialize(name, type) | ||
| 11 | @name = name | ||
| 12 | @type = type | ||
| 13 | |||
| 14 | @xmlpipe_field = [] | ||
| 15 | @xmlpipe_attr_uint = [] | ||
| 16 | @xmlpipe_attr_bool = [] | ||
| 17 | @xmlpipe_attr_timestamp = [] | ||
| 18 | @xmlpipe_attr_str2ordinal = [] | ||
| 19 | @xmlpipe_attr_float = [] | ||
| 20 | @xmlpipe_attr_multi = [] | ||
| 21 | end | ||
| 22 | |||
| 23 | def valid? | ||
| 24 | super && ( !@xmlpipe_command.nil? || !parent.nil? ) | ||
| 25 | end | ||
| 26 | end | ||
| 27 | end | ||
| 28 | end \ No newline at end of file | ||
diff --git a/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/controller.rb b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/controller.rb new file mode 100644 index 0000000..92709cd --- /dev/null +++ b/vendor/plugins/thinking-sphinx/vendor/riddle/lib/riddle/controller.rb | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | module Riddle | ||
| 2 | class Controller | ||
| 3 | def initialize(configuration, path) | ||
| 4 | @configuration = configuration | ||
| 5 | @path = path | ||
| 6 | end | ||
| 7 | |||
| 8 | def index | ||
| 9 | cmd = "indexer --config #{@path} --all" | ||
| 10 | cmd << " --rotate" if running? | ||
| 11 | `#{cmd}` | ||
| 12 | end | ||
| 13 | |||
| 14 | def start | ||
| 15 | return if running? | ||
| 16 | |||
| 17 | cmd = "searchd --pidfile --config #{@path}" | ||
| 18 | `#{cmd}` | ||
| 19 | |||
| 20 | sleep(1) | ||
| 21 | |||
| 22 | unless running? | ||
| 23 | puts "Failed to start searchd daemon. Check #{@configuration.searchd.log}." | ||
| 24 | end | ||
| 25 | end | ||
| 26 | |||
| 27 | def stop | ||
| 28 | return unless running? | ||
| 29 | `kill #{pid}` | ||
| 30 | end | ||
| 31 | |||
| 32 | def pid | ||
| 33 | if File.exists?("#{@configuration.searchd.pid_file}") | ||
| 34 | `cat #{@configuration.searchd.pid_file}`[/\d+/] | ||
| 35 | else | ||
| 36 | nil | ||
| 37 | end | ||
| 38 | end | ||
| 39 | |||
| 40 | def running? | ||
| 41 | pid && `ps #{pid} | wc -l`.to_i > 1 | ||
| 42 | end | ||
| 43 | end | ||
| 44 | end \ No newline at end of file | ||
