switchman 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/app/models/switchman/shard.rb +10 -3
- data/db/switchman_test.sqlite3 +0 -0
- data/lib/switchman/active_record/association.rb +36 -10
- data/lib/switchman/active_record/base.rb +9 -5
- data/lib/switchman/active_record/calculations.rb +12 -11
- data/lib/switchman/active_record/connection_handler.rb +102 -47
- data/lib/switchman/active_record/connection_pool.rb +3 -64
- data/lib/switchman/active_record/finder_methods.rb +1 -1
- data/lib/switchman/active_record/query_methods.rb +50 -25
- data/lib/switchman/active_record/relation.rb +5 -5
- data/lib/switchman/active_record/spawn_methods.rb +76 -29
- data/lib/switchman/connection_pool_proxy.rb +3 -1
- data/lib/switchman/database_server.rb +4 -2
- data/lib/switchman/engine.rb +8 -5
- data/lib/switchman/r_spec_helper.rb +14 -6
- data/lib/switchman/rails.rb +7 -9
- data/lib/switchman/test_helper.rb +4 -3
- data/lib/switchman/version.rb +1 -1
- data/spec/dummy/app/models/appendage.rb +2 -4
- data/spec/dummy/app/models/digit.rb +2 -4
- data/spec/dummy/app/models/feature.rb +0 -2
- data/spec/dummy/app/models/user.rb +0 -2
- data/spec/dummy/config/application.rb +0 -6
- data/spec/dummy/config/database.yml +10 -0
- data/spec/dummy/config/environments/development.rb +2 -9
- data/spec/dummy/config/environments/production.rb +2 -3
- data/spec/dummy/config/environments/test.rb +2 -11
- data/spec/dummy/config/routes.rb +2 -2
- data/spec/dummy/db/schema.rb +32 -29
- data/spec/dummy/db/switchman_test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +23 -0
- data/spec/dummy/log/test.log +36056 -86392
- data/spec/dummy/tmp/cache/2E3/840/shard%2F3 +0 -0
- data/spec/dummy/tmp/cache/2E4/850/shard%2F4 +0 -0
- data/spec/dummy/tmp/cache/2E6/870/shard%2F6 +0 -0
- data/spec/dummy/tmp/cache/2E7/880/shard%2F7 +0 -0
- data/spec/dummy/tmp/cache/{346/D90/shard%2F105 → 313/970/shard%2F30} +1 -1
- data/spec/dummy/tmp/cache/314/990/shard%2F40 +0 -0
- data/spec/dummy/tmp/cache/{31C/A40/shard%2F75 → 315/970/shard%2F14} +1 -1
- data/spec/dummy/tmp/cache/315/9A0/shard%2F41 +0 -0
- data/spec/dummy/tmp/cache/315/9B0/shard%2F50 +0 -0
- data/spec/dummy/tmp/cache/317/9C0/shard%2F43 +0 -0
- data/spec/dummy/tmp/cache/318/9B0/shard%2F26 +0 -0
- data/spec/dummy/tmp/cache/318/9D0/shard%2F44 +0 -0
- data/spec/dummy/tmp/cache/319/9C0/shard%2F27 +0 -0
- data/spec/dummy/tmp/cache/31A/9F0/shard%2F46 +0 -0
- data/spec/dummy/tmp/cache/31C/A20/shard%2F57 +0 -0
- data/spec/dummy/tmp/cache/31D/A20/shard%2F49 +0 -0
- data/spec/dummy/tmp/cache/349/E10/shard%2F153 +0 -0
- data/spec/dummy/tmp/cache/34A/E20/shard%2F154 +0 -0
- data/spec/dummy/tmp/cache/{345/DC0/shard%2F140 → 34A/E50/shard%2F181} +1 -1
- data/spec/dummy/tmp/cache/{318/A00/shard%2F71 → 34E/E70/shard%2F167} +1 -1
- data/spec/dummy/tmp/cache/375/530/shard%2F3200 +1 -0
- data/spec/dummy/tmp/cache/376/510/shard%2F2202 +1 -0
- data/spec/dummy/tmp/cache/376/520/shard%2F2211 +1 -0
- data/spec/dummy/tmp/cache/376/530/shard%2F2220 +1 -0
- data/spec/dummy/tmp/cache/377/4F0/shard%2F2014 +0 -0
- data/spec/dummy/tmp/cache/377/520/shard%2F2203 +1 -0
- data/spec/dummy/tmp/cache/377/530/shard%2F2212 +1 -0
- data/spec/dummy/tmp/cache/377/550/shard%2F2230 +1 -0
- data/spec/dummy/tmp/cache/377/550/shard%2F3040 +1 -0
- data/spec/dummy/tmp/cache/378/500/shard%2F2015 +0 -0
- data/spec/dummy/tmp/cache/378/520/shard%2F3005 +1 -0
- data/spec/dummy/tmp/cache/378/550/shard%2F2222 +1 -0
- data/spec/dummy/tmp/cache/378/560/shard%2F3122 +1 -0
- data/spec/dummy/tmp/cache/378/5A0/shard%2F2510 +1 -0
- data/spec/dummy/tmp/cache/378/5B0/shard%2F2600 +2 -0
- data/spec/dummy/tmp/cache/379/530/shard%2F3006 +1 -0
- data/spec/dummy/tmp/cache/379/540/shard%2F2205 +1 -0
- data/spec/dummy/tmp/cache/379/550/shard%2F2214 +1 -0
- data/spec/dummy/tmp/cache/379/560/shard%2F2223 +1 -0
- data/spec/dummy/tmp/cache/379/560/shard%2F3033 +1 -0
- data/spec/dummy/tmp/cache/379/560/shard%2F3114 +1 -0
- data/spec/dummy/tmp/cache/379/570/shard%2F3042 +1 -0
- data/spec/dummy/tmp/cache/379/580/shard%2F3051 +1 -0
- data/spec/dummy/tmp/cache/379/590/shard%2F3060 +1 -0
- data/spec/dummy/tmp/cache/379/5C0/shard%2F2601 +2 -0
- data/spec/dummy/tmp/cache/379/5D0/shard%2F2610 +2 -0
- data/spec/dummy/tmp/cache/37A/540/shard%2F3007 +1 -0
- data/spec/dummy/tmp/cache/37A/570/shard%2F2224 +1 -0
- data/spec/dummy/tmp/cache/37A/570/shard%2F3034 +1 -0
- data/spec/dummy/tmp/cache/37A/580/shard%2F3043 +1 -0
- data/spec/dummy/tmp/cache/37A/590/shard%2F3052 +1 -0
- data/spec/dummy/tmp/cache/37A/590/shard%2F3214 +1 -0
- data/spec/dummy/tmp/cache/37A/5A0/shard%2F3061 +1 -0
- data/spec/dummy/tmp/cache/37A/5B0/shard%2F3070 +1 -0
- data/spec/dummy/tmp/cache/37A/5E0/shard%2F2530 +0 -0
- data/spec/dummy/tmp/cache/37A/5F0/shard%2F2701 +0 -0
- data/spec/dummy/tmp/cache/37B/540/shard%2F2027 +1 -0
- data/spec/dummy/tmp/cache/37B/570/shard%2F3026 +1 -0
- data/spec/dummy/tmp/cache/37B/5C0/shard%2F2261 +1 -0
- data/spec/dummy/tmp/cache/37B/5C0/shard%2F2504 +1 -0
- data/spec/dummy/tmp/cache/37B/5C0/shard%2F3152 +1 -0
- data/spec/dummy/tmp/cache/37B/5D0/shard%2F2513 +1 -0
- data/spec/dummy/tmp/cache/37B/5E0/shard%2F2603 +2 -0
- data/spec/dummy/tmp/cache/37B/5F0/shard%2F2531 +0 -0
- data/spec/dummy/tmp/cache/37B/5F0/shard%2F2612 +2 -0
- data/spec/dummy/tmp/cache/37B/610/shard%2F2630 +2 -0
- data/spec/dummy/tmp/cache/37B/630/shard%2F2810 +2 -0
- data/spec/dummy/tmp/cache/37C/580/shard%2F2217 +1 -0
- data/spec/dummy/tmp/cache/37C/580/shard%2F3108 +1 -0
- data/spec/dummy/tmp/cache/37C/590/shard%2F3036 +1 -0
- data/spec/dummy/tmp/cache/37C/5A0/shard%2F3045 +1 -0
- data/spec/dummy/tmp/cache/37C/5B0/shard%2F3054 +1 -0
- data/spec/dummy/tmp/cache/37C/5C0/shard%2F3063 +1 -0
- data/spec/dummy/tmp/cache/37C/5D0/shard%2F2262 +1 -0
- data/spec/dummy/tmp/cache/37C/5D0/shard%2F3072 +0 -0
- data/spec/dummy/tmp/cache/37C/5E0/shard%2F2190 +1 -0
- data/spec/dummy/tmp/cache/37C/5F0/shard%2F2604 +2 -0
- data/spec/dummy/tmp/cache/37C/600/shard%2F2370 +1 -0
- data/spec/dummy/tmp/cache/37C/600/shard%2F2613 +2 -0
- data/spec/dummy/tmp/cache/37C/620/shard%2F2631 +2 -0
- data/spec/dummy/tmp/cache/37D/5A0/shard%2F3037 +1 -0
- data/spec/dummy/tmp/cache/37D/5B0/shard%2F3046 +1 -0
- data/spec/dummy/tmp/cache/37D/5C0/shard%2F3055 +1 -0
- data/spec/dummy/tmp/cache/37D/5D0/shard%2F2254 +1 -0
- data/spec/dummy/tmp/cache/37D/5D0/shard%2F3064 +1 -0
- data/spec/dummy/tmp/cache/37D/5E0/shard%2F3073 +1 -0
- data/spec/dummy/tmp/cache/37D/5F0/shard%2F2191 +1 -0
- data/spec/dummy/tmp/cache/37D/600/shard%2F2524 +1 -0
- data/spec/dummy/tmp/cache/37D/610/shard%2F2371 +1 -0
- data/spec/dummy/tmp/cache/37D/620/shard%2F2380 +1 -0
- data/spec/dummy/tmp/cache/37D/620/shard%2F2461 +1 -0
- data/spec/dummy/tmp/cache/37D/630/shard%2F2470 +1 -0
- data/spec/dummy/tmp/cache/37D/650/shard%2F2650 +0 -0
- data/spec/dummy/tmp/cache/37E/5B0/shard%2F2228 +1 -0
- data/spec/dummy/tmp/cache/37E/5D0/shard%2F3137 +1 -0
- data/spec/dummy/tmp/cache/37E/5F0/shard%2F2264 +1 -0
- data/spec/dummy/tmp/cache/37E/610/shard%2F2525 +1 -0
- data/spec/dummy/tmp/cache/37E/610/shard%2F2606 +2 -0
- data/spec/dummy/tmp/cache/37E/620/shard%2F2615 +2 -0
- data/spec/dummy/tmp/cache/37E/620/shard%2F3182 +0 -0
- data/spec/dummy/tmp/cache/37E/630/shard%2F2624 +2 -0
- data/spec/dummy/tmp/cache/37E/630/shard%2F2705 +1 -0
- data/spec/dummy/tmp/cache/37E/640/shard%2F2633 +0 -0
- data/spec/dummy/tmp/cache/37E/650/shard%2F2723 +1 -0
- data/spec/dummy/tmp/cache/37F/5C0/shard%2F2229 +1 -0
- data/spec/dummy/tmp/cache/37F/5C0/shard%2F3039 +1 -0
- data/spec/dummy/tmp/cache/37F/5E0/shard%2F3057 +1 -0
- data/spec/dummy/tmp/cache/37F/5F0/shard%2F3066 +1 -0
- data/spec/dummy/tmp/cache/37F/600/shard%2F3075 +1 -0
- data/spec/dummy/tmp/cache/37F/610/shard%2F2193 +1 -0
- data/spec/dummy/tmp/cache/37F/620/shard%2F2607 +2 -0
- data/spec/dummy/tmp/cache/37F/620/shard%2F3093 +1 -0
- data/spec/dummy/tmp/cache/37F/630/shard%2F2373 +1 -0
- data/spec/dummy/tmp/cache/37F/630/shard%2F2535 +0 -0
- data/spec/dummy/tmp/cache/37F/630/shard%2F2616 +2 -0
- data/spec/dummy/tmp/cache/37F/640/shard%2F2382 +1 -0
- data/spec/dummy/tmp/cache/37F/640/shard%2F2625 +2 -0
- data/spec/dummy/tmp/cache/37F/650/shard%2F2634 +0 -0
- data/spec/dummy/tmp/cache/380/5F0/shard%2F3058 +1 -0
- data/spec/dummy/tmp/cache/380/600/shard%2F3067 +1 -0
- data/spec/dummy/tmp/cache/380/600/shard%2F3148 +0 -0
- data/spec/dummy/tmp/cache/380/610/shard%2F2509 +1 -0
- data/spec/dummy/tmp/cache/380/610/shard%2F3076 +1 -0
- data/spec/dummy/tmp/cache/380/630/shard%2F2527 +1 -0
- data/spec/dummy/tmp/cache/380/640/shard%2F2374 +1 -0
- data/spec/dummy/tmp/cache/380/640/shard%2F2536 +0 -0
- data/spec/dummy/tmp/cache/380/660/shard%2F2473 +1 -0
- data/spec/dummy/tmp/cache/380/670/shard%2F2482 +1 -0
- data/spec/dummy/tmp/cache/380/670/shard%2F2806 +2 -0
- data/spec/dummy/tmp/cache/{2E9/8A0/shard%2F9 → 380/680/shard%2F2653} +1 -1
- data/spec/dummy/tmp/cache/380/6A0/shard%2F2671 +1 -0
- data/spec/dummy/tmp/cache/380/6A0/shard%2F2752 +2 -0
- data/spec/dummy/tmp/cache/380/6B0/shard%2F2761 +2 -0
- data/spec/dummy/tmp/cache/381/600/shard%2F2249 +1 -0
- data/spec/dummy/tmp/cache/381/610/shard%2F3149 +0 -0
- data/spec/dummy/tmp/cache/381/640/shard%2F2609 +2 -0
- data/spec/dummy/tmp/cache/381/640/shard%2F3095 +0 -0
- data/spec/dummy/tmp/cache/381/650/shard%2F3185 +1 -0
- data/spec/dummy/tmp/cache/381/660/shard%2F2627 +2 -0
- data/spec/dummy/tmp/cache/381/670/shard%2F2636 +1 -0
- data/spec/dummy/tmp/cache/381/680/shard%2F2807 +2 -0
- data/spec/dummy/tmp/cache/381/690/shard%2F2573 +1 -0
- data/spec/dummy/tmp/cache/381/6B0/shard%2F2591 +2 -0
- data/spec/dummy/tmp/cache/381/6B0/shard%2F2753 +2 -0
- data/spec/dummy/tmp/cache/381/6F0/shard%2F2870 +1 -0
- data/spec/dummy/tmp/cache/382/620/shard%2F3069 +1 -0
- data/spec/dummy/tmp/cache/382/640/shard%2F2196 +1 -0
- data/spec/dummy/tmp/cache/382/650/shard%2F3096 +0 -0
- data/spec/dummy/tmp/cache/382/650/shard%2F3177 +1 -0
- data/spec/dummy/tmp/cache/382/660/shard%2F2376 +1 -0
- data/spec/dummy/tmp/cache/382/670/shard%2F2628 +2 -0
- data/spec/dummy/tmp/cache/382/6A0/shard%2F2493 +1 -0
- data/spec/dummy/tmp/cache/382/6C0/shard%2F2592 +2 -0
- data/spec/dummy/tmp/cache/382/6C0/shard%2F2835 +1 -0
- data/spec/dummy/tmp/cache/383/650/shard%2F2197 +1 -0
- data/spec/dummy/tmp/cache/383/670/shard%2F2377 +1 -0
- data/spec/dummy/tmp/cache/383/670/shard%2F2458 +1 -0
- data/spec/dummy/tmp/cache/383/680/shard%2F2548 +1 -0
- data/spec/dummy/tmp/cache/383/690/shard%2F2476 +1 -0
- data/spec/dummy/tmp/cache/383/6A0/shard%2F2809 +2 -0
- data/spec/dummy/tmp/cache/383/6C0/shard%2F2746 +1 -0
- data/spec/dummy/tmp/cache/383/6D0/shard%2F2755 +2 -0
- data/spec/dummy/tmp/cache/383/6E0/shard%2F2764 +2 -0
- data/spec/dummy/tmp/cache/383/700/shard%2F2782 +2 -0
- data/spec/dummy/tmp/cache/383/700/shard%2F2863 +1 -0
- data/spec/dummy/tmp/cache/384/6A0/shard%2F2477 +1 -0
- data/spec/dummy/tmp/cache/384/6E0/shard%2F2594 +2 -0
- data/spec/dummy/tmp/cache/384/6E0/shard%2F2756 +2 -0
- data/spec/dummy/tmp/cache/384/6F0/shard%2F2684 +0 -0
- data/spec/dummy/tmp/cache/384/6F0/shard%2F2765 +2 -0
- data/spec/dummy/tmp/cache/384/710/shard%2F2864 +1 -0
- data/spec/dummy/tmp/cache/384/720/shard%2F2873 +1 -0
- data/spec/dummy/tmp/cache/385/670/shard%2F2199 +1 -0
- data/spec/dummy/tmp/cache/385/690/shard%2F2379 +1 -0
- data/spec/dummy/tmp/cache/385/6F0/shard%2F2595 +2 -0
- data/spec/dummy/tmp/cache/385/710/shard%2F2694 +1 -0
- data/spec/dummy/tmp/cache/386/6B0/shard%2F3199 +1 -0
- data/spec/dummy/tmp/cache/386/6C0/shard%2F2479 +1 -0
- data/spec/dummy/tmp/cache/386/700/shard%2F2758 +2 -0
- data/spec/dummy/tmp/cache/386/720/shard%2F2776 +2 -0
- data/spec/dummy/tmp/cache/386/730/shard%2F2866 +1 -0
- data/spec/dummy/tmp/cache/387/710/shard%2F2597 +2 -0
- data/spec/dummy/tmp/cache/388/720/shard%2F2598 +2 -0
- data/spec/dummy/tmp/cache/389/750/shard%2F2779 +2 -0
- data/spec/dummy/tmp/cache/389/760/shard%2F2869 +1 -0
- data/spec/dummy/tmp/cache/3A2/E80/shard%2F10010 +1 -0
- data/spec/dummy/tmp/cache/3A6/F80/shard%2F13200 +1 -0
- data/spec/dummy/tmp/cache/3A8/F70/shard%2F12203 +1 -0
- data/spec/dummy/tmp/cache/3A8/F80/shard%2F12212 +1 -0
- data/spec/dummy/tmp/cache/3A9/F50/shard%2F12015 +1 -0
- data/spec/dummy/tmp/cache/3A9/FC0/shard%2F12240 +1 -0
- data/spec/dummy/tmp/cache/3A9/FF0/shard%2F12510 +1 -0
- data/spec/dummy/tmp/cache/3AA/F10/shard%2F10027 +1 -0
- data/spec/dummy/tmp/cache/3AA/F80/shard%2F13006 +1 -0
- data/spec/dummy/tmp/cache/3AA/FB0/shard%2F12223 +1 -0
- data/spec/dummy/tmp/cache/3AA/FD0/shard%2F13132 +1 -0
- data/spec/dummy/tmp/cache/3AB/F70/shard%2F10073 +1 -0
- data/spec/dummy/tmp/cache/3AB/F70/shard%2F10154 +1 -0
- data/spec/dummy/tmp/cache/3AB/FC0/shard%2F13115 +1 -0
- data/spec/dummy/tmp/cache/3AC/050/shard%2F12702 +1 -0
- data/spec/dummy/tmp/cache/3AC/FB0/shard%2F13017 +1 -0
- data/spec/dummy/tmp/cache/3AD/010/shard%2F12253 +1 -0
- data/spec/dummy/tmp/cache/3AD/020/shard%2F12262 +1 -0
- data/spec/dummy/tmp/cache/3AE/040/shard%2F12191 +1 -0
- data/spec/dummy/tmp/cache/3AF/060/shard%2F12525 +1 -0
- data/spec/dummy/tmp/cache/3AF/0B0/shard%2F12651 +1 -0
- data/spec/dummy/tmp/cache/3B0/010/shard%2F12229 +1 -0
- data/spec/dummy/tmp/cache/3B0/080/shard%2F13183 +1 -0
- data/spec/dummy/tmp/cache/3B0/0A0/shard%2F12634 +1 -0
- data/spec/dummy/tmp/cache/3B1/070/shard%2F13166 +1 -0
- data/spec/dummy/tmp/cache/3B1/090/shard%2F12536 +1 -0
- data/spec/dummy/tmp/cache/3B1/0C0/shard%2F12563 +1 -0
- data/spec/dummy/tmp/cache/3B1/0D0/shard%2F12491 +1 -0
- data/spec/dummy/tmp/cache/3B1/0F0/shard%2F12833 +1 -0
- data/spec/dummy/tmp/cache/3B2/000/shard%2F10179 +1 -0
- data/spec/dummy/tmp/cache/3B2/060/shard%2F13149 +1 -0
- data/spec/dummy/tmp/cache/3B2/140/shard%2F12870 +1 -0
- data/spec/dummy/tmp/cache/3B3/0A0/shard%2F13096 +1 -0
- data/spec/dummy/tmp/cache/3B3/0F0/shard%2F12736 +1 -0
- data/spec/dummy/tmp/cache/3B4/090/shard%2F13079 +1 -0
- data/spec/dummy/tmp/cache/3B4/0A0/shard%2F12197 +1 -0
- data/spec/dummy/tmp/cache/3B4/0E0/shard%2F12719 +1 -0
- data/spec/dummy/tmp/cache/3B5/160/shard%2F12864 +1 -0
- data/spec/dummy/tmp/cache/3B6/150/shard%2F12685 +1 -0
- data/spec/dummy/tmp/cache/3B7/140/shard%2F12668 +1 -0
- data/spec/dummy/tmp/cache/3B9/150/shard%2F12499 +1 -0
- data/spec/lib/active_record/association_spec.rb +21 -11
- data/spec/lib/active_record/finder_methods_spec.rb +1 -1
- data/spec/lib/active_record/query_cache_spec.rb +63 -43
- data/spec/lib/active_record/query_methods_spec.rb +6 -5
- data/spec/lib/active_record/relation_spec.rb +1 -1
- data/spec/lib/active_record/spawn_methods_spec.rb +5 -4
- data/spec/lib/connection_pool_proxy_spec.rb +2 -0
- data/spec/lib/database_server_spec.rb +18 -6
- data/spec/lib/shackles_spec.rb +8 -6
- metadata +512 -59
- data/spec/dummy/tmp/cache/317/9E0/shard%2F61 +0 -0
- data/spec/dummy/tmp/cache/318/9F0/shard%2F62 +0 -0
- data/spec/dummy/tmp/cache/31A/A10/shard%2F64 +0 -0
- data/spec/dummy/tmp/cache/31A/A20/shard%2F73 +0 -0
- data/spec/dummy/tmp/cache/31B/A20/shard%2F65 +0 -0
- data/spec/dummy/tmp/cache/31B/A30/shard%2F74 +0 -0
- data/spec/dummy/tmp/cache/31D/A30/shard%2F58 +0 -0
- data/spec/dummy/tmp/cache/31D/A40/shard%2F67 +0 -0
- data/spec/dummy/tmp/cache/31E/A40/shard%2F59 +0 -0
- data/spec/dummy/tmp/cache/31E/A50/shard%2F68 +0 -0
- data/spec/dummy/tmp/cache/320/A80/shard%2F79 +0 -0
- data/spec/dummy/tmp/cache/344/D70/shard%2F103 +0 -0
- data/spec/dummy/tmp/cache/345/D80/shard%2F104 +0 -0
- data/spec/dummy/tmp/cache/349/DE0/shard%2F126 +0 -0
- data/spec/dummy/tmp/cache/34A/DF0/shard%2F127 +0 -0
- data/spec/dummy/tmp/cache/34B/E00/shard%2F128 +0 -1
- data/spec/dummy/tmp/cache/34B/E10/shard%2F137 +0 -0
- data/spec/dummy/tmp/cache/34C/E20/shard%2F138 +0 -0
- data/spec/dummy/tmp/cache/34C/E80/shard%2F192 +0 -0
|
@@ -12,36 +12,59 @@ module Switchman
|
|
|
12
12
|
# for foreign key transposition
|
|
13
13
|
# :to_a - a special value that Relation#to_a uses when querying multiple shards to
|
|
14
14
|
# remove primary keys from conditions that aren't applicable to the current shard
|
|
15
|
-
|
|
15
|
+
if ::Rails.version < '4'
|
|
16
|
+
attr_accessor :shard_value, :shard_source_value
|
|
17
|
+
else
|
|
18
|
+
def shard_value
|
|
19
|
+
@values[:shard]
|
|
20
|
+
end
|
|
21
|
+
def shard_source_value
|
|
22
|
+
@values[:shard_source]
|
|
23
|
+
end
|
|
24
|
+
def shard_value=(value)
|
|
25
|
+
raise ImmutableRelation if @loaded
|
|
26
|
+
@values[:shard] = value
|
|
27
|
+
end
|
|
28
|
+
def shard_source_value=(value)
|
|
29
|
+
raise ImmutableRelation if @loaded
|
|
30
|
+
@values[:shard_source] = value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
16
33
|
|
|
17
34
|
def shard(value, source = :explicit)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
35
|
+
(::Rails.version < '4' ? clone : spawn).shard!(value, source)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def shard!(value, source = :explicit)
|
|
39
|
+
primary_shard = self.primary_shard
|
|
40
|
+
self.shard_value = value
|
|
41
|
+
self.shard_source_value = source
|
|
42
|
+
if (primary_shard != self.primary_shard || source == :to_a)
|
|
43
|
+
self.where_values = transpose_predicates(where_values, primary_shard, self.primary_shard, source == :to_a) if !where_values.empty?
|
|
44
|
+
self.having_values = transpose_predicates(having_values, primary_shard, self.primary_shard, source == :to_a) if !having_values.empty?
|
|
24
45
|
end
|
|
25
|
-
|
|
46
|
+
self
|
|
26
47
|
end
|
|
27
48
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
49
|
+
if ::Rails.version < '4'
|
|
50
|
+
# replace these with versions that call build_where on the
|
|
51
|
+
# result relation, not the source relation (so build_where
|
|
52
|
+
# is able to implicitly change the shard_value)
|
|
53
|
+
def where(opts, *rest)
|
|
54
|
+
return self if opts.blank?
|
|
33
55
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
relation = clone
|
|
57
|
+
relation.where_values += relation.build_where(opts, rest)
|
|
58
|
+
relation
|
|
59
|
+
end
|
|
38
60
|
|
|
39
|
-
|
|
40
|
-
|
|
61
|
+
def having(opts, *rest)
|
|
62
|
+
return self if opts.blank?
|
|
41
63
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
64
|
+
relation = clone
|
|
65
|
+
relation.having_values += relation.build_where(opts, rest)
|
|
66
|
+
relation
|
|
67
|
+
end
|
|
45
68
|
end
|
|
46
69
|
|
|
47
70
|
def build_where(opts, other = [])
|
|
@@ -147,6 +170,7 @@ module Switchman
|
|
|
147
170
|
end
|
|
148
171
|
|
|
149
172
|
def sharded_primary_key?(relation, column)
|
|
173
|
+
return column == 'id' if relation.engine == ::ActiveRecord::Base
|
|
150
174
|
relation.engine.primary_key == column
|
|
151
175
|
end
|
|
152
176
|
|
|
@@ -165,6 +189,7 @@ module Switchman
|
|
|
165
189
|
attribute = attribute.relation if attribute.relation.is_a?(Arel::Nodes::TableAlias)
|
|
166
190
|
[attribute.relation, column]
|
|
167
191
|
end
|
|
192
|
+
|
|
168
193
|
# semi-private
|
|
169
194
|
public
|
|
170
195
|
def transpose_predicates(predicates, source_shard, target_shard, remove_nonlocal_primary_keys = false)
|
|
@@ -194,11 +219,11 @@ module Switchman
|
|
|
194
219
|
local_ids
|
|
195
220
|
when Arel::Nodes::BindParam
|
|
196
221
|
# look for a bind param with a matching column name
|
|
197
|
-
if
|
|
198
|
-
column, value =
|
|
222
|
+
if bind_values && idx = bind_values.find_index{|b| b.is_a?(Array) && b.first.try(:name) == predicate.left.name}
|
|
223
|
+
column, value = bind_values[idx]
|
|
199
224
|
local_id = Shard.relative_id_for(value, current_source_shard, target_shard)
|
|
200
225
|
local_id = [] if remove && local_id > Shard::IDS_PER_SHARD
|
|
201
|
-
|
|
226
|
+
bind_values[idx] = [column, local_id]
|
|
202
227
|
end
|
|
203
228
|
predicate.right
|
|
204
229
|
else
|
|
@@ -13,10 +13,10 @@ module Switchman
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def initialize_with_sharding(
|
|
17
|
-
initialize_without_sharding(
|
|
18
|
-
self.shard_value = Shard.current(klass.shard_category)
|
|
19
|
-
self.shard_source_value = :implicit
|
|
16
|
+
def initialize_with_sharding(*args)
|
|
17
|
+
initialize_without_sharding(*args)
|
|
18
|
+
self.shard_value = Shard.current(klass.try(:shard_category) || :default) unless shard_value
|
|
19
|
+
self.shard_source_value = :implicit unless shard_source_value
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def merge(*args)
|
|
@@ -62,7 +62,7 @@ module Switchman
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
%w{update_all delete_all}.each do |method|
|
|
65
|
-
class_eval <<-RUBY
|
|
65
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
66
66
|
def #{method}_with_deshackles(*args)
|
|
67
67
|
db = Shard.current(shard_category).database_server
|
|
68
68
|
if ::Shackles.environment != db.shackles_environment
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
module Switchman
|
|
2
2
|
module ActiveRecord
|
|
3
3
|
module SpawnMethods
|
|
4
|
-
def
|
|
5
|
-
return self unless r
|
|
6
|
-
return to_a & r if r.is_a?(Array)
|
|
7
|
-
|
|
8
|
-
# have to figure out shard stuff *before* conditions are merged
|
|
4
|
+
def shard_values_for_merge(r)
|
|
9
5
|
if shard_value != r.shard_value
|
|
10
|
-
if
|
|
6
|
+
if r.shard_source_value == :implicit
|
|
11
7
|
final_shard_value = shard_value
|
|
12
8
|
final_primary_shard = primary_shard
|
|
13
9
|
final_shard_source_value = shard_source_value
|
|
14
|
-
elsif
|
|
10
|
+
elsif shard_source_value == :implicit
|
|
15
11
|
final_shard_value = r.shard_value
|
|
16
12
|
final_primary_shard = r.primary_shard
|
|
17
13
|
final_shard_source_value = r.shard_source_value
|
|
@@ -30,7 +26,6 @@ module Switchman
|
|
|
30
26
|
final_primary_shard = Shard.default
|
|
31
27
|
else
|
|
32
28
|
final_shard_value = lhs_shard_value.to_a & rhs_shard_value.to_a
|
|
33
|
-
return none if final_shard_value.length == 0
|
|
34
29
|
final_primary_shard = final_shard_value.first
|
|
35
30
|
final_shard_value = final_shard_value.first if final_shard_value.length == 1
|
|
36
31
|
end
|
|
@@ -40,34 +35,86 @@ module Switchman
|
|
|
40
35
|
shard_source_value == source_value || r.shard_source_value == source_value
|
|
41
36
|
end
|
|
42
37
|
raise "unknown shard_source_value" unless final_shard_source_value
|
|
43
|
-
|
|
44
|
-
result = super
|
|
45
|
-
result.shard_source_value = final_shard_source_value
|
|
46
|
-
return result
|
|
47
38
|
else
|
|
48
39
|
# nothing fancy
|
|
49
|
-
return super
|
|
50
40
|
end
|
|
51
41
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
42
|
+
[final_shard_value, final_primary_shard, final_shard_source_value]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if ::Rails.version < '4'
|
|
46
|
+
def merge(r)
|
|
47
|
+
return self unless r
|
|
48
|
+
return super unless r.is_a?(Relation)
|
|
49
|
+
|
|
50
|
+
# have to figure out shard stuff *before* conditions are merged
|
|
51
|
+
final_shard_value, final_primary_shard, final_shard_source_value = shard_values_for_merge(r)
|
|
52
|
+
|
|
53
|
+
return super unless final_shard_source_value
|
|
54
|
+
|
|
55
|
+
if !final_shard_value
|
|
56
|
+
result = super
|
|
57
|
+
result.shard_source_value = final_shard_source_value
|
|
58
|
+
return result
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
return none if final_shard_value == []
|
|
62
|
+
|
|
63
|
+
# change the primary shard if necessary before merging
|
|
64
|
+
result = if primary_shard != final_primary_shard && r.primary_shard != final_primary_shard
|
|
65
|
+
lhs = shard(final_primary_shard)
|
|
66
|
+
r = r.shard(final_primary_shard)
|
|
67
|
+
lhs.merge(r)
|
|
68
|
+
elsif primary_shard != final_primary_shard
|
|
69
|
+
lhs = shard(final_primary_shard)
|
|
70
|
+
lhs.merge(r)
|
|
71
|
+
elsif r.primary_shard != final_primary_shard
|
|
72
|
+
r = r.shard(final_primary_shard)
|
|
73
|
+
super(r)
|
|
74
|
+
else
|
|
75
|
+
super
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
result.shard_value = final_shard_value
|
|
79
|
+
result.shard_source_value = final_shard_source_value
|
|
80
|
+
|
|
81
|
+
result
|
|
65
82
|
end
|
|
83
|
+
else
|
|
84
|
+
def merge!(r)
|
|
85
|
+
# have to figure out shard stuff *before* conditions are merged
|
|
86
|
+
final_shard_value, final_primary_shard, final_shard_source_value = shard_values_for_merge(r)
|
|
87
|
+
|
|
88
|
+
return super unless final_shard_source_value
|
|
89
|
+
|
|
90
|
+
if !final_shard_value
|
|
91
|
+
super
|
|
92
|
+
self.shard_source_value = final_shard_source_value
|
|
93
|
+
return self
|
|
94
|
+
end
|
|
66
95
|
|
|
67
|
-
|
|
68
|
-
result.shard_source_value = final_shard_source_value
|
|
96
|
+
return none! if final_shard_value == []
|
|
69
97
|
|
|
70
|
-
|
|
98
|
+
# change the primary shard if necessary before merging
|
|
99
|
+
if primary_shard != final_primary_shard && r.primary_shard != final_primary_shard
|
|
100
|
+
shard!(final_primary_shard)
|
|
101
|
+
r = r.shard(final_primary_shard)
|
|
102
|
+
super(r)
|
|
103
|
+
elsif primary_shard != final_primary_shard
|
|
104
|
+
shard!(final_primary_shard)
|
|
105
|
+
super(r)
|
|
106
|
+
elsif r.primary_shard != final_primary_shard
|
|
107
|
+
r = r.shard(final_primary_shard)
|
|
108
|
+
super(r)
|
|
109
|
+
else
|
|
110
|
+
super
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
self.shard_value = final_shard_value
|
|
114
|
+
self.shard_source_value = final_shard_source_value
|
|
115
|
+
|
|
116
|
+
self
|
|
117
|
+
end
|
|
71
118
|
end
|
|
72
119
|
end
|
|
73
120
|
end
|
|
@@ -2,6 +2,7 @@ module Switchman
|
|
|
2
2
|
module ConnectionError
|
|
3
3
|
def self.===(other)
|
|
4
4
|
return true if defined?(PG::Error) && PG::Error === other
|
|
5
|
+
return true if defined?(Mysql2::Error) && Mysql2::Error === other
|
|
5
6
|
false
|
|
6
7
|
end
|
|
7
8
|
end
|
|
@@ -90,7 +91,8 @@ module Switchman
|
|
|
90
91
|
end
|
|
91
92
|
end
|
|
92
93
|
end
|
|
93
|
-
|
|
94
|
+
klass = ::Rails.version < '4' ? ::ActiveRecord::Base : ::ActiveRecord::ConnectionAdapters
|
|
95
|
+
spec = klass::ConnectionSpecification.new(config, "#{config[:adapter]}_connection")
|
|
94
96
|
# unfortunately the AR code that does this require logic can't really be
|
|
95
97
|
# called in isolation
|
|
96
98
|
require "active_record/connection_adapters/#{config[:adapter]}_adapter"
|
|
@@ -125,7 +125,7 @@ module Switchman
|
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
def create_new_shard(options = {})
|
|
128
|
-
raise
|
|
128
|
+
raise NotImplementedError.new("Cannot create new shards when sharding isn't initialized") unless Shard.default.is_a?(Shard)
|
|
129
129
|
|
|
130
130
|
db_name = options[:db_name]
|
|
131
131
|
create_schema = options[:schema]
|
|
@@ -193,13 +193,15 @@ module Switchman
|
|
|
193
193
|
::ActiveRecord::Base.connection.execute(stmt)
|
|
194
194
|
end
|
|
195
195
|
# have to disconnect and reconnect to the correct db
|
|
196
|
+
shard.name = db_name
|
|
196
197
|
if self.shareable? && other_shard
|
|
197
198
|
other_shard.activate { ::ActiveRecord::Base.connection }
|
|
198
199
|
else
|
|
199
200
|
::ActiveRecord::Base.connection_pool.current_pool.disconnect!
|
|
200
201
|
end
|
|
202
|
+
else
|
|
203
|
+
shard.name = db_name
|
|
201
204
|
end
|
|
202
|
-
shard.name = db_name
|
|
203
205
|
old_proc = ::ActiveRecord::Base.connection.raw_connection.set_notice_processor {} if config[:adapter] == 'postgresql'
|
|
204
206
|
old_verbose = ::ActiveRecord::Migration.verbose
|
|
205
207
|
::ActiveRecord::Migration.verbose = false
|
data/lib/switchman/engine.rb
CHANGED
|
@@ -3,6 +3,9 @@ module Switchman
|
|
|
3
3
|
isolate_namespace Switchman
|
|
4
4
|
|
|
5
5
|
initializer 'switchman.initialize_cache', :before => 'initialize_cache' do
|
|
6
|
+
require "switchman/active_support/cache"
|
|
7
|
+
::ActiveSupport::Cache::Store.send(:include, ActiveSupport::Cache::Store)
|
|
8
|
+
|
|
6
9
|
# if we haven't already setup our cache map out-of-band, set it up from
|
|
7
10
|
# config.cache_store now. behaves similarly to Rails' default
|
|
8
11
|
# initialize_cache initializer, but for each value in the map, rather
|
|
@@ -46,11 +49,13 @@ module Switchman
|
|
|
46
49
|
else
|
|
47
50
|
::Rails.cache = Switchman.config[:cache_map][::Rails.env]
|
|
48
51
|
end
|
|
52
|
+
|
|
53
|
+
require "switchman/rails"
|
|
54
|
+
::Rails.send(:include, Rails)
|
|
49
55
|
end
|
|
50
56
|
|
|
51
57
|
initializer 'switchman.extend_ar', :before => "active_record.initialize_database" do
|
|
52
58
|
::ActiveSupport.on_load(:active_record) do
|
|
53
|
-
require "switchman/active_support/cache"
|
|
54
59
|
require "switchman/active_record/abstract_adapter"
|
|
55
60
|
require "switchman/active_record/association"
|
|
56
61
|
require "switchman/active_record/attribute_methods"
|
|
@@ -64,15 +69,13 @@ module Switchman
|
|
|
64
69
|
require "switchman/active_record/query_methods"
|
|
65
70
|
require "switchman/active_record/relation"
|
|
66
71
|
require "switchman/active_record/spawn_methods"
|
|
67
|
-
require "switchman/rails"
|
|
68
72
|
|
|
69
|
-
::ActiveSupport::Cache::Store.send(:include, ActiveSupport::Cache::Store)
|
|
70
73
|
include ActiveRecord::Base
|
|
71
74
|
include ActiveRecord::AttributeMethods
|
|
72
75
|
::ActiveRecord::Associations::Association.send(:include, ActiveRecord::Association)
|
|
73
76
|
::ActiveRecord::Associations::BelongsToAssociation.send(:include, ActiveRecord::BelongsToAssociation)
|
|
74
77
|
::ActiveRecord::Associations::CollectionProxy.send(:include, ActiveRecord::CollectionProxy)
|
|
75
|
-
::ActiveRecord::Associations::Builder::
|
|
78
|
+
::ActiveRecord::Associations::Builder::CollectionAssociation.send(:include, ActiveRecord::Builder::CollectionAssociation)
|
|
76
79
|
|
|
77
80
|
::ActiveRecord::Associations::Preloader::Association.send(:include, ActiveRecord::Preloader::Association)
|
|
78
81
|
::ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, ActiveRecord::AbstractAdapter)
|
|
@@ -91,7 +94,6 @@ module Switchman
|
|
|
91
94
|
::ActiveRecord::Relation.send(:include, ActiveRecord::QueryMethods)
|
|
92
95
|
::ActiveRecord::Relation.send(:include, ActiveRecord::Relation)
|
|
93
96
|
::ActiveRecord::Relation.send(:include, ActiveRecord::SpawnMethods)
|
|
94
|
-
::Rails.send(:include, Rails)
|
|
95
97
|
end
|
|
96
98
|
end
|
|
97
99
|
|
|
@@ -104,6 +106,7 @@ module Switchman
|
|
|
104
106
|
initializer 'switchman.extend_connection_adapters', :after => "active_record.initialize_database" do
|
|
105
107
|
::ActiveSupport.on_load(:active_record) do
|
|
106
108
|
::ActiveRecord::ConnectionAdapters::AbstractAdapter.descendants.each do |klass|
|
|
109
|
+
next if klass.instance_methods.include?(:add_column_with_foreign_key_check)
|
|
107
110
|
klass.class_eval do
|
|
108
111
|
def add_column_with_foreign_key_check(table, name, type, options = {})
|
|
109
112
|
Switchman::Engine.foreign_key_check(name, type, options)
|
|
@@ -96,9 +96,13 @@ module Switchman
|
|
|
96
96
|
shards.each do |shard|
|
|
97
97
|
shard.activate do
|
|
98
98
|
# this is how AR does it in fixtures.rb
|
|
99
|
-
::
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
if ::Rails.version < '4'
|
|
100
|
+
::ActiveRecord::Base.connection.increment_open_transactions
|
|
101
|
+
::ActiveRecord::Base.connection.transaction_joinable = false
|
|
102
|
+
::ActiveRecord::Base.connection.begin_db_transaction
|
|
103
|
+
else
|
|
104
|
+
::ActiveRecord::Base.connection.begin_transaction joinable: false
|
|
105
|
+
end
|
|
102
106
|
end
|
|
103
107
|
end
|
|
104
108
|
end
|
|
@@ -110,9 +114,13 @@ module Switchman
|
|
|
110
114
|
shards << @shard1 unless @shard1.database_server == Shard.default.database_server
|
|
111
115
|
shards.each do |shard|
|
|
112
116
|
shard.activate do
|
|
113
|
-
if ::
|
|
114
|
-
::ActiveRecord::Base.connection.
|
|
115
|
-
|
|
117
|
+
if ::Rails.version < '4'
|
|
118
|
+
if ::ActiveRecord::Base.connection.open_transactions != 0
|
|
119
|
+
::ActiveRecord::Base.connection.rollback_db_transaction
|
|
120
|
+
::ActiveRecord::Base.connection.decrement_open_transactions
|
|
121
|
+
end
|
|
122
|
+
else
|
|
123
|
+
::ActiveRecord::Base.connection.rollback_transaction if ::ActiveRecord::Base.connection.transaction_open?
|
|
116
124
|
end
|
|
117
125
|
end
|
|
118
126
|
end
|
data/lib/switchman/rails.rb
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
module Switchman::Rails
|
|
2
2
|
module ClassMethods
|
|
3
|
-
def
|
|
3
|
+
def cache
|
|
4
4
|
Switchman::Shard.current.database_server.cache_store
|
|
5
5
|
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.included(klass)
|
|
9
|
+
klass.extend(ClassMethods)
|
|
10
|
+
klass.singleton_class.send(:remove_method, :cache)
|
|
6
11
|
|
|
7
12
|
# in Rails 4+, the Rails.cache= method was used during bootstrap to set
|
|
8
13
|
# Rails.cache(_without_sharding) to the value from the config file. but now
|
|
9
14
|
# that that's done (the bootstrap happened before this module is included
|
|
10
15
|
# into Rails), we want to make sure no one tries to assign to Rails.cache,
|
|
11
16
|
# because it would be wrong w.r.t. sharding.
|
|
12
|
-
|
|
13
|
-
raise NoMethodError
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def self.included(klass)
|
|
18
|
-
klass.extend(ClassMethods)
|
|
19
|
-
klass.singleton_class.alias_method_chain :cache, :sharding
|
|
17
|
+
klass.singleton_class.send(:remove_method, :cache=) if ::Rails.version >= '4'
|
|
20
18
|
end
|
|
21
19
|
end
|
|
@@ -5,9 +5,9 @@ module Switchman
|
|
|
5
5
|
# recreate the default shard (it got buhleted)
|
|
6
6
|
if Shard.default(true).is_a?(DefaultShard)
|
|
7
7
|
begin
|
|
8
|
-
Shard.create!(:
|
|
8
|
+
Shard.create!(default: true)
|
|
9
9
|
rescue
|
|
10
|
-
# database doesn't exist yet, presumably
|
|
10
|
+
# database doesn't exist yet, presumably cause we're creating it right now
|
|
11
11
|
[nil, nil]
|
|
12
12
|
end
|
|
13
13
|
Shard.default(true)
|
|
@@ -15,7 +15,8 @@ module Switchman
|
|
|
15
15
|
|
|
16
16
|
# can't auto-create a new shard on the default shard's db server if the
|
|
17
17
|
# default shard is split across multiple db servers
|
|
18
|
-
if ::ActiveRecord::Base.connection_handler.connection_pools.length
|
|
18
|
+
if (::Rails.version < '4' ? ::ActiveRecord::Base.connection_handler.connection_pools.length :
|
|
19
|
+
::ActiveRecord::Base.connection_handler.connection_pool_list.length) > 1
|
|
19
20
|
server1 = DatabaseServer.create(:config => Shard.default.database_server.config)
|
|
20
21
|
else
|
|
21
22
|
server1 = Shard.default.database_server
|
data/lib/switchman/version.rb
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
class Appendage < ActiveRecord::Base
|
|
2
|
-
attr_accessible :user, :user_id, :value
|
|
3
|
-
|
|
4
2
|
belongs_to :user
|
|
5
3
|
has_many :digits
|
|
6
4
|
|
|
7
5
|
has_many :features, :as => :owner
|
|
8
6
|
|
|
9
|
-
scope :has_no_value, where(:value => nil)
|
|
10
|
-
scope :has_value, where("appendages.value IS NOT NULL")
|
|
7
|
+
scope :has_no_value, -> { where(:value => nil) }
|
|
8
|
+
scope :has_value, -> { where("appendages.value IS NOT NULL") }
|
|
11
9
|
|
|
12
10
|
attr_writer :associated_shards
|
|
13
11
|
class << self
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
class Digit < ActiveRecord::Base
|
|
2
|
-
attr_accessible :appendage, :appendage_id, :value
|
|
3
|
-
|
|
4
2
|
belongs_to :appendage
|
|
5
3
|
has_one :user, :through => :appendage
|
|
6
4
|
|
|
7
|
-
scope :has_no_value, where(:value => nil)
|
|
8
|
-
scope :has_value, where("digits.value IS NOT NULL")
|
|
5
|
+
scope :has_no_value, -> { where(:value => nil) }
|
|
6
|
+
scope :has_value, -> { where("digits.value IS NOT NULL") }
|
|
9
7
|
end
|
|
@@ -43,12 +43,6 @@ module Dummy
|
|
|
43
43
|
# like if you have constraints or database-specific column types
|
|
44
44
|
# config.active_record.schema_format = :sql
|
|
45
45
|
|
|
46
|
-
# Enforce whitelist mode for mass assignment.
|
|
47
|
-
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
|
48
|
-
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
|
49
|
-
# parameters by using an attr_accessible or attr_protected declaration.
|
|
50
|
-
config.active_record.whitelist_attributes = true
|
|
51
|
-
|
|
52
46
|
# Enable the asset pipeline
|
|
53
47
|
config.assets.enabled = true
|
|
54
48
|
|
|
@@ -15,3 +15,13 @@ test:
|
|
|
15
15
|
adapter: postgresql
|
|
16
16
|
database: switchman_test
|
|
17
17
|
port: 15432
|
|
18
|
+
|
|
19
|
+
testm:
|
|
20
|
+
adapter: mysql2
|
|
21
|
+
database: switchman_test
|
|
22
|
+
socket: /opt/boxen/data/mysql/socket
|
|
23
|
+
username: root
|
|
24
|
+
|
|
25
|
+
tests:
|
|
26
|
+
adapter: sqlite3
|
|
27
|
+
database: db/switchman_test.sqlite3
|
|
@@ -6,25 +6,16 @@ Dummy::Application.configure do
|
|
|
6
6
|
# since you don't have to restart the web server when you make code changes.
|
|
7
7
|
config.cache_classes = false
|
|
8
8
|
|
|
9
|
-
# Log error messages when you accidentally call methods on nil.
|
|
10
|
-
config.whiny_nils = true
|
|
11
|
-
|
|
12
9
|
# Show full error reports and disable caching
|
|
13
10
|
config.consider_all_requests_local = true
|
|
14
11
|
config.action_controller.perform_caching = false
|
|
15
12
|
|
|
16
|
-
# Don't care if the mailer can't send
|
|
17
|
-
config.action_mailer.raise_delivery_errors = false
|
|
18
|
-
|
|
19
13
|
# Print deprecation notices to the Rails logger
|
|
20
14
|
config.active_support.deprecation = :log
|
|
21
15
|
|
|
22
16
|
# Only use best-standards-support built into browsers
|
|
23
17
|
config.action_dispatch.best_standards_support = :builtin
|
|
24
18
|
|
|
25
|
-
# Raise exception on mass assignment protection for Active Record models
|
|
26
|
-
config.active_record.mass_assignment_sanitizer = :strict
|
|
27
|
-
|
|
28
19
|
# Log the query plan for queries taking more than this (works
|
|
29
20
|
# with SQLite, MySQL, and PostgreSQL)
|
|
30
21
|
config.active_record.auto_explain_threshold_in_seconds = 0.5
|
|
@@ -34,4 +25,6 @@ Dummy::Application.configure do
|
|
|
34
25
|
|
|
35
26
|
# Expands the lines which load the assets
|
|
36
27
|
config.assets.debug = true
|
|
28
|
+
|
|
29
|
+
config.eager_load = false
|
|
37
30
|
end
|
|
@@ -48,9 +48,6 @@ Dummy::Application.configure do
|
|
|
48
48
|
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
|
49
49
|
# config.assets.precompile += %w( search.js )
|
|
50
50
|
|
|
51
|
-
# Disable delivery errors, bad email addresses will be ignored
|
|
52
|
-
# config.action_mailer.raise_delivery_errors = false
|
|
53
|
-
|
|
54
51
|
# Enable threaded mode
|
|
55
52
|
# config.threadsafe!
|
|
56
53
|
|
|
@@ -64,4 +61,6 @@ Dummy::Application.configure do
|
|
|
64
61
|
# Log the query plan for queries taking more than this (works
|
|
65
62
|
# with SQLite, MySQL, and PostgreSQL)
|
|
66
63
|
# config.active_record.auto_explain_threshold_in_seconds = 0.5
|
|
64
|
+
|
|
65
|
+
config.eager_load = true
|
|
67
66
|
end
|
|
@@ -11,9 +11,6 @@ Dummy::Application.configure do
|
|
|
11
11
|
config.serve_static_assets = true
|
|
12
12
|
config.static_cache_control = "public, max-age=3600"
|
|
13
13
|
|
|
14
|
-
# Log error messages when you accidentally call methods on nil
|
|
15
|
-
config.whiny_nils = true
|
|
16
|
-
|
|
17
14
|
# Show full error reports and disable caching
|
|
18
15
|
config.consider_all_requests_local = true
|
|
19
16
|
config.action_controller.perform_caching = false
|
|
@@ -24,14 +21,8 @@ Dummy::Application.configure do
|
|
|
24
21
|
# Disable request forgery protection in test environment
|
|
25
22
|
config.action_controller.allow_forgery_protection = false
|
|
26
23
|
|
|
27
|
-
# Tell Action Mailer not to deliver emails to the real world.
|
|
28
|
-
# The :test delivery method accumulates sent emails in the
|
|
29
|
-
# ActionMailer::Base.deliveries array.
|
|
30
|
-
config.action_mailer.delivery_method = :test
|
|
31
|
-
|
|
32
|
-
# Raise exception on mass assignment protection for Active Record models
|
|
33
|
-
config.active_record.mass_assignment_sanitizer = :strict
|
|
34
|
-
|
|
35
24
|
# Print deprecation notices to the stderr
|
|
36
25
|
config.active_support.deprecation = :stderr
|
|
26
|
+
|
|
27
|
+
config.eager_load = false
|
|
37
28
|
end
|
data/spec/dummy/config/routes.rb
CHANGED
|
@@ -3,6 +3,6 @@ Dummy::Application.routes.draw do
|
|
|
3
3
|
resources :appendages
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
get 'users/:id' => 'users#test1', :as => :user_test1
|
|
7
|
+
get 'users/:user_id/test2' => 'users#test2', :as => :user_test2
|
|
8
8
|
end
|