spiderfw 0.5.19 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. data/CHANGELOG +7 -0
  2. data/VERSION +1 -1
  3. data/apps/core/auth/lib/rbac.rb +7 -2
  4. data/apps/core/auth/models/mixins/rbac_provider.rb +66 -4
  5. data/apps/core/components/assets.rb +63 -33
  6. data/apps/core/components/public/js/jquery/{jquery-1.4.3.js → jquery-1.5.2.js} +2617 -1126
  7. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.apple.js +155 -0
  8. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.js +293 -0
  9. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/scrollable/scrollable.js +335 -0
  10. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.css +59 -0
  11. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.js +283 -0
  12. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/toolbox/toolbox.expose.js +224 -0
  13. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.dynamic.js +150 -0
  14. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.js +343 -0
  15. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.slide.js +78 -0
  16. 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
  17. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/datepicker.gif +0 -0
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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
  39. 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
  40. 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
  41. 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
  42. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ar-DZ.js +23 -0
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-AU.js +23 -0
  53. 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
  54. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-NZ.js +23 -0
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-gl.js +23 -0
  65. 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
  66. 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
  67. 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
  68. 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
  69. 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
  70. 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
  71. 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
  72. 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
  73. 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
  74. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-kz.js +23 -0
  75. 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
  76. 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
  77. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ml.js +23 -0
  78. 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
  79. 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
  80. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-no.js +23 -0
  81. 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
  82. 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
  83. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-pt.js +22 -0
  84. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-rm.js +21 -0
  85. 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
  86. 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
  87. 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
  88. 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
  89. 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
  90. 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
  91. 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
  92. 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
  93. 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
  94. 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
  95. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-tj.js +23 -0
  96. 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
  97. 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
  98. 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
  99. 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
  100. 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
  101. 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
  102. 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
  103. 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
  104. 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
  105. 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
  106. 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
  107. 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
  108. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/jquery.effects.fade.js +32 -0
  109. 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
  110. 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
  111. 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
  112. 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
  113. 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
  114. 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
  115. 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
  116. 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
  117. 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
  118. 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
  119. 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
  120. 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
  121. 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
  122. 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
  123. 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
  124. 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
  125. 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
  126. 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
  127. 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
  128. 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
  129. 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
  130. 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
  131. 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
  132. 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
  133. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/GPL-LICENSE.txt +1 -1
  134. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/MIT-LICENSE.txt +3 -7
  135. data/apps/core/components/public/js/jquery/plugins/bsmselect/README.md +185 -0
  136. data/apps/core/components/public/js/jquery/plugins/bsmselect/css/jquery.bsmselect.css +64 -0
  137. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.compatibility.js +60 -0
  138. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.js +381 -0
  139. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.sortable.js +49 -0
  140. data/apps/core/components/public/js/plugins/sortable.js +16 -7
  141. data/apps/core/components/public/js/spider.js +60 -41
  142. data/apps/core/components/widgets/admin/admin.shtml +1 -1
  143. data/apps/core/components/widgets/list/list.shtml +2 -2
  144. data/apps/core/components/widgets/month_calendar/month_calendar.shtml +23 -20
  145. data/apps/core/components/widgets/switcher/switcher.rb +77 -21
  146. data/apps/core/components/widgets/switcher/templates/default.shtml +8 -0
  147. data/apps/core/components/widgets/switcher/templates/table.shtml +15 -0
  148. data/apps/core/components/widgets/table/table.rb +4 -1
  149. data/apps/core/components/widgets/table/table.shtml +10 -8
  150. data/apps/core/forms/public/css/form.css +9 -1
  151. data/apps/core/forms/public/date_time.js +14 -2
  152. data/apps/core/forms/public/input.js +1 -1
  153. data/apps/core/forms/public/select.js +4 -3
  154. data/apps/core/forms/tags/element_row.erb +11 -2
  155. data/apps/core/forms/widgets/inputs/date_time/date_time.rb +9 -0
  156. data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +1 -1
  157. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
  158. data/apps/core/forms/widgets/inputs/input/input.rb +0 -3
  159. data/apps/core/forms/widgets/inputs/select/select.shtml +2 -2
  160. data/apps/messenger/backends/email/sendmail.rb +20 -0
  161. data/apps/messenger/backends/email/smtp.rb +12 -14
  162. data/apps/messenger/backends/email/test.rb +20 -0
  163. data/apps/messenger/config/options.rb +9 -9
  164. data/apps/messenger/config/test.config.yml +2 -0
  165. data/apps/messenger/controllers/mixins/messenger_helper.rb +41 -15
  166. data/apps/messenger/lib/email_backend.rb +10 -0
  167. data/apps/messenger/messenger.rb +45 -26
  168. data/apps/messenger/test/features/attachments.feature +26 -0
  169. data/apps/messenger/test/features/messenger_helper.feature +31 -0
  170. data/apps/messenger/test/features/sending_email.feature +10 -0
  171. data/apps/messenger/test/features/step_definitions/common_steps.rb +11 -0
  172. data/apps/messenger/test/features/step_definitions/email_steps.rb +98 -0
  173. data/apps/messenger/test/features/support/env.rb +11 -0
  174. data/apps/messenger/test/files/test_file1.txt +1 -0
  175. data/apps/messenger/test/lib/controllers/mail_test_controller.rb +34 -0
  176. data/apps/messenger/test/templates/email/multipart.html.erb +1 -0
  177. data/apps/messenger/test/templates/email/multipart.txt.erb +1 -0
  178. data/apps/messenger/test/templates/email/simple.erb +1 -0
  179. data/apps/messenger/test/templates/email/vars.erb +1 -0
  180. data/lib/spiderfw/cmd/cmd.rb +4 -0
  181. data/lib/spiderfw/cmd/commands/webserver.rb +12 -59
  182. data/lib/spiderfw/config/configuration.rb +4 -0
  183. data/lib/spiderfw/config/options/spider.rb +25 -8
  184. data/lib/spiderfw/controller/controller.rb +10 -4
  185. data/lib/spiderfw/controller/first_responder.rb +6 -20
  186. data/lib/spiderfw/controller/http_controller.rb +2 -1
  187. data/lib/spiderfw/controller/mixins/http_mixin.rb +12 -1
  188. data/lib/spiderfw/controller/mixins/visual.rb +3 -16
  189. data/lib/spiderfw/env.rb +1 -1
  190. data/lib/spiderfw/http/server.rb +178 -2
  191. data/lib/spiderfw/model/base_model.rb +142 -111
  192. data/lib/spiderfw/model/data_type.rb +15 -0
  193. data/lib/spiderfw/model/datatypes/decimal.rb +8 -0
  194. data/lib/spiderfw/model/datatypes/pk.rb +29 -0
  195. data/lib/spiderfw/model/datatypes.rb +1 -0
  196. data/lib/spiderfw/model/element.rb +5 -1
  197. data/lib/spiderfw/model/extended_models/managed.rb +1 -1
  198. data/lib/spiderfw/model/junction.rb +23 -0
  199. data/lib/spiderfw/model/mappers/db_mapper.rb +96 -80
  200. data/lib/spiderfw/model/mappers/document_mapper.rb +315 -0
  201. data/lib/spiderfw/model/mappers/mapper.rb +164 -75
  202. data/lib/spiderfw/model/mixins/list.rb +1 -0
  203. data/lib/spiderfw/model/mixins/versioned.rb +63 -27
  204. data/lib/spiderfw/model/model.rb +36 -9
  205. data/lib/spiderfw/model/query_funcs.rb +3 -0
  206. data/lib/spiderfw/model/query_set.rb +21 -1
  207. data/lib/spiderfw/model/storage/base_storage.rb +259 -6
  208. data/lib/spiderfw/model/storage/{db/db_connection_pool.rb → connection_pool.rb} +25 -21
  209. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +25 -5
  210. data/lib/spiderfw/model/storage/db/adapters/oracle.rb +1 -1
  211. data/lib/spiderfw/model/storage/db/connectors/jdbc_oracle.rb +2 -2
  212. data/lib/spiderfw/model/storage/db/connectors/oci8.rb +3 -4
  213. data/lib/spiderfw/model/storage/db/db_storage.rb +18 -219
  214. data/lib/spiderfw/model/storage/document/adapters/mongodb.rb +307 -0
  215. data/lib/spiderfw/model/storage/document/document.rb +7 -0
  216. data/lib/spiderfw/model/storage/document/document_storage.rb +34 -0
  217. data/lib/spiderfw/model/storage.rb +23 -11
  218. data/lib/spiderfw/model/unit_of_work.rb +45 -22
  219. data/lib/spiderfw/spider.rb +660 -0
  220. data/lib/spiderfw/templates/blocks/html.rb +4 -2
  221. data/lib/spiderfw/templates/blocks/run.rb +1 -1
  222. data/lib/spiderfw/templates/blocks/tag_if.rb +1 -1
  223. data/lib/spiderfw/templates/blocks/widget.rb +1 -1
  224. data/lib/spiderfw/templates/layout.rb +29 -5
  225. data/lib/spiderfw/templates/template.rb +72 -7
  226. data/lib/spiderfw/templates/template_blocks.rb +1 -1
  227. data/lib/spiderfw/test/capybara.rb +7 -0
  228. data/lib/spiderfw/test/cucumber.rb +12 -0
  229. data/lib/spiderfw/test/page_object.rb +29 -0
  230. data/lib/spiderfw/test/spec.rb +20 -0
  231. data/lib/spiderfw/test/stubs/mapper_stub.rb +18 -0
  232. data/lib/spiderfw/test/stubs/storage_stub.rb +23 -0
  233. data/lib/spiderfw/test/unit.rb +23 -0
  234. data/lib/spiderfw/test.rb +89 -0
  235. data/lib/spiderfw/utils/json.rb +6 -0
  236. data/lib/spiderfw/utils/logger.rb +17 -4
  237. data/lib/spiderfw/utils/loggers/apache_commons_logger.rb +61 -0
  238. data/lib/spiderfw/utils/monkey/date_time.rb +2 -2
  239. data/lib/spiderfw/utils/monkey/module.rb +3 -1
  240. data/lib/spiderfw/utils/profiling.rb +2 -2
  241. data/lib/spiderfw/widget/widget.rb +31 -13
  242. data/lib/spiderfw.rb +1 -597
  243. data/spider.gemspec +9 -10
  244. metadata +193 -132
  245. data/apps/admin/_init.rb +0 -9
  246. data/apps/admin/controllers/admin_controller.rb +0 -12
  247. data/apps/admin/widgets/dashboard_widget/dashboard_widget.rb +0 -8
  248. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/AUTHORS.txt +0 -30
  249. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery-ui-i18n.js +0 -1176
  250. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery.ui.datepicker-no.js +0 -23
  251. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/version.txt +0 -1
  252. data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.css +0 -64
  253. data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.js +0 -407
  254. data/apps/core/components/widgets/switcher/switcher.shtml +0 -17
  255. data/apps/master/po/master.pot +0 -400
@@ -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 (klass.subclass_of?(Spider::DataType) && klass.maps_to)
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
- obj = mod.new(row)
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
- sorter = Sorter.new(models)
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
 
@@ -122,6 +122,9 @@ module Spider; module QueryFuncs
122
122
 
123
123
  class CurrentDate < ZeroArityFunction
124
124
  end
125
+
126
+ class RowNum < ZeroArityFunction
127
+ end
125
128
 
126
129
  class Length < UnaryFunction
127
130
  end
@@ -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
- attr_accessor :loaded
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
- def self.sequence_sync
9
- @sequence_sync ||= ::Sync.new
10
- end
10
+ @capabilities = {
11
+
12
+ }
11
13
 
12
- def self.base_types
13
- Model.base_types
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; module Db
3
+ module Spider; module Model; module Storage
4
4
 
5
- class DbConnectionPool
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.db.pool.size')
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.db.pool.timeout')
17
- @retry = Spider.conf.get('storage.db.pool.retry')
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
- Thread.current[:db_connections] ||= {}
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[:db_connections][@connection_params]
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[:db_connections][@connection_params] = conn
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[:db_connections].delete(@connection_params)
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 db connection in #{@timeout} seconds" if @timeout
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("DB Pool (#{Thread.current}): connection #{conn} dead")
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("DB Pool (#{Thread.current}): creating new connection #{conn} (#{@connections.length} already in pool)")
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; 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
@@ -359,7 +359,7 @@ module Spider; module Model; module Storage; module Db
359
359
  end
360
360
 
361
361
  def column_name(name)
362
- super.upcase
362
+ shorten_identifier(super, 30).upcase
363
363
  end
364
364
 
365
365
  def sequence_name(name)