spiderfw 0.5.19 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/VERSION +1 -1
- data/apps/core/auth/lib/rbac.rb +7 -2
- data/apps/core/auth/models/mixins/rbac_provider.rb +66 -4
- data/apps/core/components/assets.rb +63 -33
- data/apps/core/components/public/js/jquery/{jquery-1.4.3.js → jquery-1.5.2.js} +2617 -1126
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.apple.js +155 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.js +293 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/scrollable/scrollable.js +335 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.css +59 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.js +283 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/toolbox/toolbox.expose.js +224 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.dynamic.js +150 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.js +343 -0
- data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.slide.js +78 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/button_bg.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/datepicker.gif +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/icon_sprite.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/progress_bar.gif +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_h_bg.gif +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_handles.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_v_bg.gif +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/tab_bg.gif +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/the_gradient.gif +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-anim_basic_16x16.gif +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_222222_256x240.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_228ef1_256x240.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ef8c08_256x240.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ffd27a_256x240.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ffffff_256x240.png +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/jquery-ui.custom.css +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-af.js +0 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ar-DZ.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ar.js +7 -8
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-az.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-bg.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-bs.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ca.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-cs.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-da.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-de.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-el.js +0 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-AU.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-en-GB.js +0 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-NZ.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-eo.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-es.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-et.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-eu.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fa.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fi.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fo.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fr-CH.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fr.js +12 -10
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-gl.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-he.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hr.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hu.js +1 -1
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hy.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-id.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-is.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-it.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ja.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ko.js +0 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-kz.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-lt.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-lv.js +0 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ml.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ms.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-nl.js +0 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-no.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-pl.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-pt-BR.js +0 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-pt.js +22 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-rm.js +21 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ro.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ru.js +1 -1
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sk.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sl.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sq.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sr-SR.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sr.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sv.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ta.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-th.js +1 -1
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-tj.js +23 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-tr.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-uk.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-vi.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-CN.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-HK.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-TW.js +0 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.blind.js +3 -3
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.bounce.js +3 -3
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.clip.js +3 -3
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.core.js +48 -15
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.drop.js +3 -3
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.explode.js +2 -2
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/jquery.effects.fade.js +32 -0
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.fold.js +3 -3
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.highlight.js +2 -2
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.pulsate.js +2 -2
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.scale.js +4 -4
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.shake.js +3 -3
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.slide.js +4 -4
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.transfer.js +2 -2
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.accordion.js +33 -20
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.autocomplete.js +104 -42
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.button.js +35 -13
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.core.js +111 -84
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.datepicker.js +87 -46
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.dialog.js +105 -75
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.draggable.js +17 -15
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.droppable.js +5 -5
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.mouse.js +16 -11
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.position.js +51 -32
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.progressbar.js +24 -10
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.resizable.js +7 -7
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.selectable.js +3 -3
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.slider.js +9 -7
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.sortable.js +22 -20
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.tabs.js +15 -14
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.widget.js +50 -25
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/GPL-LICENSE.txt +1 -1
- data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/MIT-LICENSE.txt +3 -7
- data/apps/core/components/public/js/jquery/plugins/bsmselect/README.md +185 -0
- data/apps/core/components/public/js/jquery/plugins/bsmselect/css/jquery.bsmselect.css +64 -0
- data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.compatibility.js +60 -0
- data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.js +381 -0
- data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.sortable.js +49 -0
- data/apps/core/components/public/js/plugins/sortable.js +16 -7
- data/apps/core/components/public/js/spider.js +60 -41
- data/apps/core/components/widgets/admin/admin.shtml +1 -1
- data/apps/core/components/widgets/list/list.shtml +2 -2
- data/apps/core/components/widgets/month_calendar/month_calendar.shtml +23 -20
- data/apps/core/components/widgets/switcher/switcher.rb +77 -21
- data/apps/core/components/widgets/switcher/templates/default.shtml +8 -0
- data/apps/core/components/widgets/switcher/templates/table.shtml +15 -0
- data/apps/core/components/widgets/table/table.rb +4 -1
- data/apps/core/components/widgets/table/table.shtml +10 -8
- data/apps/core/forms/public/css/form.css +9 -1
- data/apps/core/forms/public/date_time.js +14 -2
- data/apps/core/forms/public/input.js +1 -1
- data/apps/core/forms/public/select.js +4 -3
- data/apps/core/forms/tags/element_row.erb +11 -2
- data/apps/core/forms/widgets/inputs/date_time/date_time.rb +9 -0
- data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +1 -1
- data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
- data/apps/core/forms/widgets/inputs/input/input.rb +0 -3
- data/apps/core/forms/widgets/inputs/select/select.shtml +2 -2
- data/apps/messenger/backends/email/sendmail.rb +20 -0
- data/apps/messenger/backends/email/smtp.rb +12 -14
- data/apps/messenger/backends/email/test.rb +20 -0
- data/apps/messenger/config/options.rb +9 -9
- data/apps/messenger/config/test.config.yml +2 -0
- data/apps/messenger/controllers/mixins/messenger_helper.rb +41 -15
- data/apps/messenger/lib/email_backend.rb +10 -0
- data/apps/messenger/messenger.rb +45 -26
- data/apps/messenger/test/features/attachments.feature +26 -0
- data/apps/messenger/test/features/messenger_helper.feature +31 -0
- data/apps/messenger/test/features/sending_email.feature +10 -0
- data/apps/messenger/test/features/step_definitions/common_steps.rb +11 -0
- data/apps/messenger/test/features/step_definitions/email_steps.rb +98 -0
- data/apps/messenger/test/features/support/env.rb +11 -0
- data/apps/messenger/test/files/test_file1.txt +1 -0
- data/apps/messenger/test/lib/controllers/mail_test_controller.rb +34 -0
- data/apps/messenger/test/templates/email/multipart.html.erb +1 -0
- data/apps/messenger/test/templates/email/multipart.txt.erb +1 -0
- data/apps/messenger/test/templates/email/simple.erb +1 -0
- data/apps/messenger/test/templates/email/vars.erb +1 -0
- data/lib/spiderfw/cmd/cmd.rb +4 -0
- data/lib/spiderfw/cmd/commands/webserver.rb +12 -59
- data/lib/spiderfw/config/configuration.rb +4 -0
- data/lib/spiderfw/config/options/spider.rb +25 -8
- data/lib/spiderfw/controller/controller.rb +10 -4
- data/lib/spiderfw/controller/first_responder.rb +6 -20
- data/lib/spiderfw/controller/http_controller.rb +2 -1
- data/lib/spiderfw/controller/mixins/http_mixin.rb +12 -1
- data/lib/spiderfw/controller/mixins/visual.rb +3 -16
- data/lib/spiderfw/env.rb +1 -1
- data/lib/spiderfw/http/server.rb +178 -2
- data/lib/spiderfw/model/base_model.rb +142 -111
- data/lib/spiderfw/model/data_type.rb +15 -0
- data/lib/spiderfw/model/datatypes/decimal.rb +8 -0
- data/lib/spiderfw/model/datatypes/pk.rb +29 -0
- data/lib/spiderfw/model/datatypes.rb +1 -0
- data/lib/spiderfw/model/element.rb +5 -1
- data/lib/spiderfw/model/extended_models/managed.rb +1 -1
- data/lib/spiderfw/model/junction.rb +23 -0
- data/lib/spiderfw/model/mappers/db_mapper.rb +96 -80
- data/lib/spiderfw/model/mappers/document_mapper.rb +315 -0
- data/lib/spiderfw/model/mappers/mapper.rb +164 -75
- data/lib/spiderfw/model/mixins/list.rb +1 -0
- data/lib/spiderfw/model/mixins/versioned.rb +63 -27
- data/lib/spiderfw/model/model.rb +36 -9
- data/lib/spiderfw/model/query_funcs.rb +3 -0
- data/lib/spiderfw/model/query_set.rb +21 -1
- data/lib/spiderfw/model/storage/base_storage.rb +259 -6
- data/lib/spiderfw/model/storage/{db/db_connection_pool.rb → connection_pool.rb} +25 -21
- data/lib/spiderfw/model/storage/db/adapters/mysql.rb +25 -5
- data/lib/spiderfw/model/storage/db/adapters/oracle.rb +1 -1
- data/lib/spiderfw/model/storage/db/connectors/jdbc_oracle.rb +2 -2
- data/lib/spiderfw/model/storage/db/connectors/oci8.rb +3 -4
- data/lib/spiderfw/model/storage/db/db_storage.rb +18 -219
- data/lib/spiderfw/model/storage/document/adapters/mongodb.rb +307 -0
- data/lib/spiderfw/model/storage/document/document.rb +7 -0
- data/lib/spiderfw/model/storage/document/document_storage.rb +34 -0
- data/lib/spiderfw/model/storage.rb +23 -11
- data/lib/spiderfw/model/unit_of_work.rb +45 -22
- data/lib/spiderfw/spider.rb +660 -0
- data/lib/spiderfw/templates/blocks/html.rb +4 -2
- data/lib/spiderfw/templates/blocks/run.rb +1 -1
- data/lib/spiderfw/templates/blocks/tag_if.rb +1 -1
- data/lib/spiderfw/templates/blocks/widget.rb +1 -1
- data/lib/spiderfw/templates/layout.rb +29 -5
- data/lib/spiderfw/templates/template.rb +72 -7
- data/lib/spiderfw/templates/template_blocks.rb +1 -1
- data/lib/spiderfw/test/capybara.rb +7 -0
- data/lib/spiderfw/test/cucumber.rb +12 -0
- data/lib/spiderfw/test/page_object.rb +29 -0
- data/lib/spiderfw/test/spec.rb +20 -0
- data/lib/spiderfw/test/stubs/mapper_stub.rb +18 -0
- data/lib/spiderfw/test/stubs/storage_stub.rb +23 -0
- data/lib/spiderfw/test/unit.rb +23 -0
- data/lib/spiderfw/test.rb +89 -0
- data/lib/spiderfw/utils/json.rb +6 -0
- data/lib/spiderfw/utils/logger.rb +17 -4
- data/lib/spiderfw/utils/loggers/apache_commons_logger.rb +61 -0
- data/lib/spiderfw/utils/monkey/date_time.rb +2 -2
- data/lib/spiderfw/utils/monkey/module.rb +3 -1
- data/lib/spiderfw/utils/profiling.rb +2 -2
- data/lib/spiderfw/widget/widget.rb +31 -13
- data/lib/spiderfw.rb +1 -597
- data/spider.gemspec +9 -10
- metadata +193 -132
- data/apps/admin/_init.rb +0 -9
- data/apps/admin/controllers/admin_controller.rb +0 -12
- data/apps/admin/widgets/dashboard_widget/dashboard_widget.rb +0 -8
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/AUTHORS.txt +0 -30
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery-ui-i18n.js +0 -1176
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery.ui.datepicker-no.js +0 -23
- data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/version.txt +0 -1
- data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.css +0 -64
- data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.js +0 -407
- data/apps/core/components/widgets/switcher/switcher.shtml +0 -17
- data/apps/master/po/master.pot +0 -400
data/lib/spiderfw/model/model.rb
CHANGED
@@ -8,7 +8,7 @@ module Spider
|
|
8
8
|
|
9
9
|
@base_types = [
|
10
10
|
String, Spider::DataTypes::Text, Fixnum, Float, BigDecimal, Date, DateTime, Time,
|
11
|
-
Spider::DataTypes::Bool
|
11
|
+
Spider::DataTypes::Bool, Spider::DataTypes::PK
|
12
12
|
]
|
13
13
|
|
14
14
|
# Base types are:
|
@@ -50,7 +50,7 @@ module Spider
|
|
50
50
|
return klass if base_types.include?(klass)
|
51
51
|
return klass if klass <= Spider::Model::BaseModel
|
52
52
|
return t if t = map_types[klass]
|
53
|
-
return klass.maps_to if
|
53
|
+
return klass.maps_to if klass.subclass_of?(Spider::DataType) && klass.maps_to
|
54
54
|
return klass.superclass if klass.superclass
|
55
55
|
return nil
|
56
56
|
end
|
@@ -126,6 +126,10 @@ module Spider
|
|
126
126
|
self.unit_of_work = uow
|
127
127
|
end
|
128
128
|
|
129
|
+
def self.unit_of_work_running?
|
130
|
+
self.unit_of_work && self.unit_of_work.running?
|
131
|
+
end
|
132
|
+
|
129
133
|
def self.no_identity_mapper(&proc)
|
130
134
|
im = self.identity_mapper
|
131
135
|
self.identity_mapper = nil
|
@@ -136,7 +140,7 @@ module Spider
|
|
136
140
|
def self.no_context(&proc)
|
137
141
|
uow = self.unit_of_work
|
138
142
|
self.unit_of_work = nil
|
139
|
-
im = self.identity_mapper
|
143
|
+
im = self.identity_mapper
|
140
144
|
self.identity_mapper = nil
|
141
145
|
yield
|
142
146
|
self.identity_mapper = im
|
@@ -212,7 +216,7 @@ module Spider
|
|
212
216
|
end
|
213
217
|
|
214
218
|
# Load YAML data
|
215
|
-
def self.load_fixtures(file)
|
219
|
+
def self.load_fixtures(file, truncate=false)
|
216
220
|
if (file =~ /\.([^\.]+)$/)
|
217
221
|
extension = $1
|
218
222
|
else
|
@@ -229,8 +233,20 @@ module Spider
|
|
229
233
|
data.each do |step|
|
230
234
|
step.each do |mod_name, mod_data|
|
231
235
|
mod = const_get_full(mod_name)
|
236
|
+
mod.mapper.truncate! if truncate
|
232
237
|
mod_data.each do |row|
|
233
|
-
|
238
|
+
h = {}
|
239
|
+
row.each do |k, v|
|
240
|
+
if v.is_a?(String)
|
241
|
+
if v[0..1] == '@@'
|
242
|
+
v = v[1..-1]
|
243
|
+
elsif v[0].chr == '@'
|
244
|
+
v = eval(v[1..-1].to_s)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
h[k] = v
|
248
|
+
end
|
249
|
+
obj = mod.new(h)
|
234
250
|
obj.insert
|
235
251
|
end
|
236
252
|
end
|
@@ -268,9 +284,11 @@ module Spider
|
|
268
284
|
class TypeError < ArgumentError
|
269
285
|
end
|
270
286
|
|
271
|
-
def self.sort(models)
|
272
|
-
|
273
|
-
|
287
|
+
def self.sort(models, options={})
|
288
|
+
options = {
|
289
|
+
:association_dependencies => true
|
290
|
+
}.merge(options)
|
291
|
+
sorter = Sorter.new(models, options)
|
274
292
|
sorter.sort
|
275
293
|
end
|
276
294
|
|
@@ -279,11 +297,12 @@ module Spider
|
|
279
297
|
class Sorter
|
280
298
|
include TSort
|
281
299
|
|
282
|
-
def initialize(models)
|
300
|
+
def initialize(models, options={})
|
283
301
|
@model_tasks = {}
|
284
302
|
@processed_deps = {}
|
285
303
|
@processed = {}
|
286
304
|
@models = models
|
305
|
+
@options = options
|
287
306
|
@models.each{ |m| collect_dependencies(m) }
|
288
307
|
end
|
289
308
|
|
@@ -303,6 +322,14 @@ module Spider
|
|
303
322
|
@model_tasks[model.superclass] ||= SortTask.new(model.superclass)
|
304
323
|
@model_tasks[model] << @model_tasks[model.superclass]
|
305
324
|
end
|
325
|
+
if @options[:association_dependencies]
|
326
|
+
model.elements.each do |name, element|
|
327
|
+
if element.model? && !element.attributes[:added_reverse] && @models.include?(element.type)
|
328
|
+
@model_tasks[element.type] ||= SortTask.new(element.type)
|
329
|
+
@model_tasks[model] << @model_tasks[element.type]
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
306
333
|
end
|
307
334
|
|
308
335
|
|
@@ -28,7 +28,7 @@ module Spider; module Model
|
|
28
28
|
# Total number of objects present in the Storage for the Query
|
29
29
|
attr_accessor :total_rows
|
30
30
|
# (bool) Wether the QuerySet has been loaded
|
31
|
-
|
31
|
+
attr_reader :loaded
|
32
32
|
# (Fixnum) How many objects to load at a time. If nil, all the objects returned by the Query
|
33
33
|
# will be loaded.
|
34
34
|
attr_accessor :fetch_window
|
@@ -50,6 +50,7 @@ module Spider; module Model
|
|
50
50
|
attr_accessor :loadable # :nodoc: TODO: remove?
|
51
51
|
# Don't put this queryset's objects into the IdentityMapper
|
52
52
|
attr_accessor :_no_identity_mapper
|
53
|
+
attr_accessor :modified
|
53
54
|
|
54
55
|
# Instantiates a non-autoloading queryset
|
55
56
|
def self.static(model, query_or_val=nil)
|
@@ -172,6 +173,7 @@ module Spider; module Model
|
|
172
173
|
end
|
173
174
|
index_object(obj)
|
174
175
|
@raw_data[@objects.length-1] = raw if raw
|
176
|
+
@modified = true
|
175
177
|
end
|
176
178
|
|
177
179
|
|
@@ -221,6 +223,14 @@ module Spider; module Model
|
|
221
223
|
@loaded_elements.merge!(f_loaded)
|
222
224
|
end
|
223
225
|
|
226
|
+
def modified?
|
227
|
+
return true if @modified
|
228
|
+
@objects.each do |obj|
|
229
|
+
return true if obj.modified?
|
230
|
+
end
|
231
|
+
return false
|
232
|
+
end
|
233
|
+
|
224
234
|
# Returns the last object.
|
225
235
|
def last
|
226
236
|
load unless (@loaded || !autoload?) && loaded?(total_rows-1)
|
@@ -232,6 +242,10 @@ module Spider; module Model
|
|
232
242
|
@objects.delete_at(index)
|
233
243
|
end
|
234
244
|
|
245
|
+
def delete(obj)
|
246
|
+
@objects.delete(obj)
|
247
|
+
end
|
248
|
+
|
235
249
|
# Returns a new QuerySet containing objects from both this and the other.
|
236
250
|
def +(other)
|
237
251
|
qs = self.clone
|
@@ -456,6 +470,7 @@ module Spider; module Model
|
|
456
470
|
return load_next if @fetch_window && !@query.offset
|
457
471
|
mapper.find(@query.clone, self)
|
458
472
|
@loaded = true
|
473
|
+
@modified = false
|
459
474
|
return self
|
460
475
|
end
|
461
476
|
|
@@ -500,6 +515,11 @@ module Spider; module Model
|
|
500
515
|
return false
|
501
516
|
end
|
502
517
|
|
518
|
+
def loaded=(val)
|
519
|
+
@loaded = val
|
520
|
+
@modified = false if @loaded
|
521
|
+
end
|
522
|
+
|
503
523
|
def loadable?
|
504
524
|
@loadable
|
505
525
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spiderfw/model/storage/connection_pool'
|
2
|
+
|
1
3
|
module Spider; module Model; module Storage
|
2
4
|
|
3
5
|
class BaseStorage
|
@@ -5,14 +7,82 @@ module Spider; module Model; module Storage
|
|
5
7
|
attr_reader :url
|
6
8
|
attr_accessor :instance_name
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
@capabilities = {
|
11
|
+
|
12
|
+
}
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
class << self
|
15
|
+
# An Hash of storage capabilities. The default for db storages is
|
16
|
+
# {:autoincrement => false, :sequences => true, :transactions => true}
|
17
|
+
# (The BaseStorage class provides file sequences in case the subclass does not support them.)
|
18
|
+
attr_reader :capabilities
|
19
|
+
|
20
|
+
def storage_type
|
21
|
+
:none
|
22
|
+
end
|
23
|
+
|
24
|
+
def sequence_sync
|
25
|
+
@sequence_sync ||= ::Sync.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def base_types
|
29
|
+
Model.base_types
|
30
|
+
end
|
31
|
+
|
32
|
+
# True if given named capability is supported by the Storage.
|
33
|
+
def supports?(capability)
|
34
|
+
@capabilities[capability]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns a new connection. Must be implemented by the subclasses; args are implementation specific.
|
38
|
+
def new_connection(*args)
|
39
|
+
raise "Unimplemented"
|
40
|
+
end
|
41
|
+
|
42
|
+
def max_connections
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def connection_pools
|
47
|
+
@pools ||= {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_connection(*args)
|
51
|
+
@pools ||= {}
|
52
|
+
@pools[args] ||= ConnectionPool.new(args, self)
|
53
|
+
@pools[args].get_connection
|
54
|
+
end
|
55
|
+
|
56
|
+
# Frees a connection, relasing it to the pool
|
57
|
+
def release_connection(conn, conn_params)
|
58
|
+
return unless conn
|
59
|
+
return unless @pools && @pools[conn_params]
|
60
|
+
@pools[conn_params].release(conn)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Removes a connection from the pool.
|
64
|
+
def remove_connection(conn, conn_params)
|
65
|
+
return unless conn
|
66
|
+
return unless @pools && @pools[conn_params]
|
67
|
+
@pools[conn_params].remove(conn)
|
68
|
+
end
|
69
|
+
|
70
|
+
def disconnect(conn)
|
71
|
+
raise "Virtual"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Checks whether a connection is still alive. Must be implemented by subclasses.
|
75
|
+
def connection_alive?(conn)
|
76
|
+
raise "Virtual"
|
77
|
+
end
|
78
|
+
|
79
|
+
def inherited(subclass)
|
80
|
+
subclass.instance_variable_set("@capabilities", @capabilities)
|
81
|
+
end
|
82
|
+
|
14
83
|
end
|
15
84
|
|
85
|
+
|
16
86
|
def initialize(url)
|
17
87
|
@url = url
|
18
88
|
@configuration = {}
|
@@ -31,6 +101,89 @@ module Spider; module Model; module Storage
|
|
31
101
|
raise StorageException, "Unimplemented"
|
32
102
|
end
|
33
103
|
|
104
|
+
def supports?(capability)
|
105
|
+
self.class.supports?(capability)
|
106
|
+
end
|
107
|
+
|
108
|
+
def curr
|
109
|
+
var = nil
|
110
|
+
if Spider.conf.get('storage.shared_connection')
|
111
|
+
$STORAGES ||= {}
|
112
|
+
var = $STORAGES
|
113
|
+
else
|
114
|
+
var = Thread.current
|
115
|
+
end
|
116
|
+
var[:storages] ||= {}
|
117
|
+
var[:storages][self.class.storage_type] ||= {}
|
118
|
+
var[:storages][self.class.storage_type][@connection_params] ||= {
|
119
|
+
:transaction_nesting => 0, :savepoints => []
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
def connection_pool
|
124
|
+
self.class.connection_pools[@connection_params]
|
125
|
+
end
|
126
|
+
|
127
|
+
# Instantiates a new connection with current connection params.
|
128
|
+
def connect
|
129
|
+
return self.class.get_connection(*@connection_params)
|
130
|
+
#Spider::Logger.debug("#{self.class.name} in thread #{Thread.current} acquired connection #{@conn}")
|
131
|
+
end
|
132
|
+
|
133
|
+
# True if currently connected.
|
134
|
+
def connected?
|
135
|
+
curr[:conn] != nil
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
# Returns the current connection, or creates a new one.
|
140
|
+
# If a block is given, will release the connection after yielding.
|
141
|
+
def connection
|
142
|
+
curr[:conn] = connect
|
143
|
+
if block_given?
|
144
|
+
yield curr[:conn]
|
145
|
+
release # unless is_connected
|
146
|
+
return true
|
147
|
+
else
|
148
|
+
return curr[:conn]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.connection_attributes
|
153
|
+
@connection_attributes ||= {}
|
154
|
+
end
|
155
|
+
|
156
|
+
def connection_attributes
|
157
|
+
self.class.connection_attributes[connection] ||= {}
|
158
|
+
end
|
159
|
+
|
160
|
+
# Releases the current connection to the pool.
|
161
|
+
def release
|
162
|
+
# The subclass should check if the connection is alive, and if it is not call remove_connection instead
|
163
|
+
c = curr[:conn]
|
164
|
+
#Spider.logger.debug("#{self} in thread #{Thread.current} releasing #{curr[:conn]}")
|
165
|
+
curr[:conn] = nil
|
166
|
+
self.class.release_connection(c, @connection_params)
|
167
|
+
#Spider.logger.debug("#{self} in thread #{Thread.current} released #{curr[:conn]}")
|
168
|
+
return nil
|
169
|
+
#@conn = nil
|
170
|
+
end
|
171
|
+
|
172
|
+
# Prepares a value for saving.
|
173
|
+
def value_for_save(type, value, save_mode)
|
174
|
+
return prepare_value(type, value)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Prepares a value that will be used in a condition.
|
178
|
+
def value_for_condition(type, value)
|
179
|
+
return prepare_value(type, value)
|
180
|
+
end
|
181
|
+
|
182
|
+
def value_to_mapper(type, value)
|
183
|
+
value
|
184
|
+
end
|
185
|
+
|
186
|
+
|
34
187
|
def prepare_value(type, value)
|
35
188
|
return value
|
36
189
|
end
|
@@ -41,6 +194,106 @@ module Spider; module Model; module Storage
|
|
41
194
|
return true
|
42
195
|
end
|
43
196
|
|
197
|
+
|
198
|
+
def supports_transactions?
|
199
|
+
return self.class.supports?(:transactions)
|
200
|
+
end
|
201
|
+
|
202
|
+
def transactions_enabled?
|
203
|
+
@configuration['enable_transactions'] && supports_transactions?
|
204
|
+
end
|
205
|
+
|
206
|
+
def start_transaction
|
207
|
+
return unless transactions_enabled?
|
208
|
+
curr[:transaction_nesting] += 1
|
209
|
+
return savepoint("point#{curr[:savepoints].length}") if in_transaction?
|
210
|
+
|
211
|
+
Spider.logger.debug("#{self.class.name} starting transaction for connection #{connection.object_id}")
|
212
|
+
do_start_transaction
|
213
|
+
return true
|
214
|
+
end
|
215
|
+
|
216
|
+
# May be implemented by subclasses.
|
217
|
+
def do_start_transaction
|
218
|
+
raise StorageException, "The current storage does not support transactions"
|
219
|
+
end
|
220
|
+
|
221
|
+
def in_transaction
|
222
|
+
if in_transaction?
|
223
|
+
curr[:transaction_nesting] += 1
|
224
|
+
return true
|
225
|
+
else
|
226
|
+
start_transaction
|
227
|
+
return false
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def in_transaction?
|
232
|
+
return false
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
def commit
|
237
|
+
return false unless transactions_enabled?
|
238
|
+
raise StorageException, "Commit without a transaction" unless in_transaction?
|
239
|
+
return curr[:savepoints].pop unless curr[:savepoints].empty?
|
240
|
+
commit!
|
241
|
+
end
|
242
|
+
|
243
|
+
def commit_or_continue
|
244
|
+
return false unless transactions_enabled?
|
245
|
+
raise StorageException, "Commit without a transaction" unless in_transaction?
|
246
|
+
if curr[:transaction_nesting] == 1
|
247
|
+
commit
|
248
|
+
curr[:transaction_nesting] = 0
|
249
|
+
return true
|
250
|
+
else
|
251
|
+
curr[:transaction_nesting] -= 1
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def commit!
|
256
|
+
Spider.logger.debug("#{self.class.name} commit connection #{curr[:conn].object_id}")
|
257
|
+
curr[:transaction_nesting] = 0
|
258
|
+
do_commit
|
259
|
+
release
|
260
|
+
end
|
261
|
+
|
262
|
+
def do_commit
|
263
|
+
raise StorageException, "The current storage does not support transactions"
|
264
|
+
end
|
265
|
+
|
266
|
+
def rollback
|
267
|
+
raise "Can't rollback in a nested transaction" if curr[:transaction_nesting] > 1
|
268
|
+
return rollback_savepoint(curr[:savepoints].last) unless curr[:savepoints].empty?
|
269
|
+
rollback!
|
270
|
+
end
|
271
|
+
|
272
|
+
def rollback!
|
273
|
+
curr[:transaction_nesting] = 0
|
274
|
+
Spider.logger.debug("#{self.class.name} rollback")
|
275
|
+
do_rollback
|
276
|
+
curr[:savepoints] = []
|
277
|
+
release
|
278
|
+
end
|
279
|
+
|
280
|
+
def do_rollback
|
281
|
+
raise StorageException, "The current storage does not support transactions"
|
282
|
+
end
|
283
|
+
|
284
|
+
def savepoint(name)
|
285
|
+
curr[:savepoints] << name
|
286
|
+
end
|
287
|
+
|
288
|
+
def rollback_savepoint(name=nil)
|
289
|
+
if name
|
290
|
+
curr[:savepoints] = curr[:savepoints][0,(curr[:savepoints].index(name))]
|
291
|
+
name
|
292
|
+
else
|
293
|
+
curr[:savepoints].pop
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
44
297
|
# Utility methods
|
45
298
|
|
46
299
|
def sequence_file_path(name)
|
@@ -99,7 +352,7 @@ module Spider; module Model; module Storage
|
|
99
352
|
self.class.sequence_sync.lock(::Sync::UN)
|
100
353
|
return seq
|
101
354
|
end
|
102
|
-
|
355
|
+
|
103
356
|
|
104
357
|
end
|
105
358
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'monitor'
|
2
2
|
|
3
|
-
module Spider; module Model; module Storage
|
3
|
+
module Spider; module Model; module Storage
|
4
4
|
|
5
|
-
class
|
5
|
+
class ConnectionPool
|
6
6
|
attr_reader :max_size
|
7
7
|
attr_accessor :timeout, :retry
|
8
8
|
|
@@ -11,21 +11,13 @@ module Spider; module Model; module Storage; module Db
|
|
11
11
|
@provider = provider
|
12
12
|
@connection_mutex = Monitor.new
|
13
13
|
@queue = @connection_mutex.new_cond
|
14
|
-
@max_size = Spider.conf.get('storage.
|
14
|
+
@max_size = Spider.conf.get('storage.pool.size')
|
15
15
|
@max_size = provider.max_connections if provider.max_connections && provider.max_connections < @max_size
|
16
|
-
@timeout = Spider.conf.get('storage.
|
17
|
-
@retry = Spider.conf.get('storage.
|
16
|
+
@timeout = Spider.conf.get('storage.pool.timeout')
|
17
|
+
@retry = Spider.conf.get('storage.pool.retry')
|
18
18
|
@connections = []
|
19
19
|
@free_connections = []
|
20
20
|
@thread_connections = {}
|
21
|
-
# if Spider.runmode == 'devel'
|
22
|
-
# Thread.new do
|
23
|
-
# loop do
|
24
|
-
# Spider.logger.debug("DB Pool: #{@connections.length} connections, #{@free_connections.length} free")
|
25
|
-
# sleep(10)
|
26
|
-
# end
|
27
|
-
# end
|
28
|
-
# end
|
29
21
|
end
|
30
22
|
|
31
23
|
def size
|
@@ -35,18 +27,27 @@ module Spider; module Model; module Storage; module Db
|
|
35
27
|
def free_size
|
36
28
|
@free_connections.length
|
37
29
|
end
|
30
|
+
|
31
|
+
def storage_type
|
32
|
+
@provider.storage_type
|
33
|
+
end
|
38
34
|
|
39
35
|
def get_connection
|
40
|
-
|
36
|
+
if Spider.conf.get('storage.shared_connection')
|
37
|
+
@shared_conn ||= _checkout
|
38
|
+
return @shared_conn
|
39
|
+
end
|
40
|
+
Thread.current[:storage_connections] ||= {}
|
41
|
+
Thread.current[:storage_connections][storage_type] ||= {}
|
41
42
|
@connection_mutex.synchronize do
|
42
43
|
#Spider.logger.debug("DB Pool (#{Thread.current}): trying to get connection")
|
43
|
-
if conn = Thread.current[:
|
44
|
+
if conn = Thread.current[:storage_connections][storage_type][@connection_params]
|
44
45
|
#Spider.logger.debug("DB Pool (#{Thread.current}): returning thread connection #{conn}")
|
45
46
|
@free_connections.delete(conn)
|
46
47
|
conn
|
47
48
|
else
|
48
49
|
conn = _checkout
|
49
|
-
Thread.current[:
|
50
|
+
Thread.current[:storage_connections][storage_type][@connection_params] = conn
|
50
51
|
@thread_connections[Thread.current.object_id] = [conn, Time.now]
|
51
52
|
conn
|
52
53
|
end
|
@@ -60,10 +61,13 @@ module Spider; module Model; module Storage; module Db
|
|
60
61
|
end
|
61
62
|
|
62
63
|
def release(conn)
|
64
|
+
if Spider.conf.get('storage.shared_connection')
|
65
|
+
return
|
66
|
+
end
|
63
67
|
@connection_mutex.synchronize do
|
64
68
|
#Spider.logger.debug("DB Pool (#{Thread.current}): releasing #{conn}")
|
65
69
|
@free_connections << conn
|
66
|
-
Thread.current[:
|
70
|
+
Thread.current[:storage_connections][storage_type].delete(@connection_params)
|
67
71
|
@thread_connections.delete(Thread.current.object_id)
|
68
72
|
@queue.signal
|
69
73
|
end
|
@@ -102,7 +106,7 @@ module Spider; module Model; module Storage; module Db
|
|
102
106
|
create_new_connection if @free_connections.empty? && @connections.length < @max_size
|
103
107
|
if @free_connections.empty?
|
104
108
|
Spider.logger.error "#{Thread.current} GOT TIRED WAITING, #{@queue.count_waiters} IN QUEUE"
|
105
|
-
raise StorageException, "Unable to get a
|
109
|
+
raise StorageException, "Unable to get a #{storage_type} connection in #{@timeout} seconds" if @timeout
|
106
110
|
end
|
107
111
|
end
|
108
112
|
end
|
@@ -111,7 +115,7 @@ module Spider; module Model; module Storage; module Db
|
|
111
115
|
end
|
112
116
|
conn = @free_connections.pop
|
113
117
|
while conn && !@provider.connection_alive?(conn)
|
114
|
-
Spider.logger.warn("
|
118
|
+
Spider.logger.warn("Storage #{storage_type} Pool (#{Thread.current}): connection #{conn} dead")
|
115
119
|
remove_connection(conn)
|
116
120
|
conn = nil
|
117
121
|
conn = @free_connections.pop unless @free_connections.empty?
|
@@ -158,7 +162,7 @@ module Spider; module Model; module Storage; module Db
|
|
158
162
|
|
159
163
|
def create_new_connection
|
160
164
|
conn = @provider.new_connection(*@connection_params)
|
161
|
-
Spider.logger.debug("
|
165
|
+
Spider.logger.debug("Storage #{storage_type } Pool (#{Thread.current}): creating new connection #{conn} (#{@connections.length} already in pool)")
|
162
166
|
@connections << conn
|
163
167
|
@free_connections << conn
|
164
168
|
end
|
@@ -168,4 +172,4 @@ module Spider; module Model; module Storage; module Db
|
|
168
172
|
end
|
169
173
|
|
170
174
|
|
171
|
-
end; end; end
|
175
|
+
end; end; end
|
@@ -84,12 +84,17 @@ module Spider; module Model; module Storage; module Db
|
|
84
84
|
conn.close
|
85
85
|
end
|
86
86
|
|
87
|
+
def configure(conf)
|
88
|
+
super
|
89
|
+
@configuration['default_engine'] ||= Spider.conf.get('db.mysql.default_engine')
|
90
|
+
end
|
91
|
+
|
87
92
|
def release
|
88
93
|
begin
|
89
94
|
#Spider::Logger.debug("MYSQL #{self.object_id} in thread #{Thread.current} releasing connection #{@conn}")
|
90
|
-
@conn.autocommit(true) if @conn
|
95
|
+
@conn.autocommit(true) if @conn && !Spider.conf.get('storage.db.shared_connection')
|
91
96
|
super
|
92
|
-
rescue exc
|
97
|
+
rescue => exc
|
93
98
|
Spider::Logger.error("MYSQL #{self.object_id} in thread #{Thread.current} exception #{exc.message} while trying to release connection #{@conn}")
|
94
99
|
self.class.remove_connection(@conn, @connection_params)
|
95
100
|
@conn = nil
|
@@ -151,7 +156,7 @@ module Spider; module Model; module Storage; module Db
|
|
151
156
|
end
|
152
157
|
|
153
158
|
def do_rollback
|
154
|
-
curr[:conn].rollback
|
159
|
+
curr[:conn].rollback if curr[:conn]
|
155
160
|
curr[:in_transaction] = false
|
156
161
|
end
|
157
162
|
|
@@ -168,10 +173,10 @@ module Spider; module Model; module Storage; module Db
|
|
168
173
|
curr[:last_executed] = [sql, bind_vars]
|
169
174
|
if (Spider.conf.get('storage.db.replace_debug_vars'))
|
170
175
|
cnt = -1
|
171
|
-
debug("mysql executing: "+sql.gsub('?'){ debug_vars[cnt+=1] })
|
176
|
+
debug("mysql #{curr[:conn]} executing: "+sql.gsub('?'){ debug_vars[cnt+=1] })
|
172
177
|
else
|
173
178
|
debug_vars_str = debug_vars ? debug_vars.join(', ') : ''
|
174
|
-
debug("mysql executing:\n#{sql}\n[#{debug_vars_str}]")
|
179
|
+
debug("mysql #{curr[:conn]} executing:\n#{sql}\n[#{debug_vars_str}]")
|
175
180
|
end
|
176
181
|
query_start
|
177
182
|
stmt = connection.prepare(sql)
|
@@ -300,6 +305,12 @@ module Spider; module Model; module Storage; module Db
|
|
300
305
|
return sql
|
301
306
|
end
|
302
307
|
|
308
|
+
def sql_create_table(create)
|
309
|
+
sqls = super
|
310
|
+
sqls[0] += " ENGINE=#{@configuration['default_engine']}" if @configuration['default_engine']
|
311
|
+
sqls
|
312
|
+
end
|
313
|
+
|
303
314
|
def function(func)
|
304
315
|
return super unless func.func_name == :concat
|
305
316
|
fields = func.elements.map{ |func_el|
|
@@ -426,6 +437,15 @@ module Spider; module Model; module Storage; module Db
|
|
426
437
|
return db_attributes
|
427
438
|
end
|
428
439
|
|
440
|
+
def function(func)
|
441
|
+
case func.func_name
|
442
|
+
when :rownum
|
443
|
+
"if(@rn, @rn:=@rn+1, @rn:=1)-1"
|
444
|
+
else
|
445
|
+
super
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
429
449
|
def schema_field_text_equal?(current, field)
|
430
450
|
# FIXME
|
431
451
|
return true
|