qwikdoc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +2 -0
  3. data/CHANGES +3 -0
  4. data/COPYING +340 -0
  5. data/Gemfile +3 -0
  6. data/README.md +10 -0
  7. data/Rakefile +10 -0
  8. data/TextFormattingRules +137 -0
  9. data/TextFormattingRules.ja +143 -0
  10. data/bin/qwikdoc +34 -0
  11. data/lib/qwik_doc.rb +15 -0
  12. data/lib/qwik_doc/hack.rb +184 -0
  13. data/qwikdoc.gemspec +26 -0
  14. data/spec/qwik_doc_spec.rb +305 -0
  15. data/spec/spec_helper.rb +12 -0
  16. data/vendor/qwik/Makefile +63 -0
  17. data/vendor/qwik/Rakefile +17 -0
  18. data/vendor/qwik/act-aa.rb +83 -0
  19. data/vendor/qwik/act-archive.rb +386 -0
  20. data/vendor/qwik/act-attach.rb +304 -0
  21. data/vendor/qwik/act-backup.rb +236 -0
  22. data/vendor/qwik/act-basic.rb +325 -0
  23. data/vendor/qwik/act-book.rb +161 -0
  24. data/vendor/qwik/act-calc.rb +371 -0
  25. data/vendor/qwik/act-charset.rb +251 -0
  26. data/vendor/qwik/act-christel.rb +112 -0
  27. data/vendor/qwik/act-chronology.rb +149 -0
  28. data/vendor/qwik/act-code.rb +155 -0
  29. data/vendor/qwik/act-comment.rb +554 -0
  30. data/vendor/qwik/act-config.rb +49 -0
  31. data/vendor/qwik/act-counter.rb +125 -0
  32. data/vendor/qwik/act-day.rb +96 -0
  33. data/vendor/qwik/act-describe.rb +135 -0
  34. data/vendor/qwik/act-diary.rb +109 -0
  35. data/vendor/qwik/act-edit.rb +317 -0
  36. data/vendor/qwik/act-embed-html.rb +296 -0
  37. data/vendor/qwik/act-emode.rb +150 -0
  38. data/vendor/qwik/act-event.rb +187 -0
  39. data/vendor/qwik/act-file.rb +303 -0
  40. data/vendor/qwik/act-files.rb +771 -0
  41. data/vendor/qwik/act-getpass.rb +295 -0
  42. data/vendor/qwik/act-history.rb +136 -0
  43. data/vendor/qwik/act-html.rb +204 -0
  44. data/vendor/qwik/act-httpauth.rb +147 -0
  45. data/vendor/qwik/act-include.rb +142 -0
  46. data/vendor/qwik/act-interwiki.rb +189 -0
  47. data/vendor/qwik/act-isearch.rb +109 -0
  48. data/vendor/qwik/act-keywords.rb +137 -0
  49. data/vendor/qwik/act-lang.rb +81 -0
  50. data/vendor/qwik/act-license.rb +63 -0
  51. data/vendor/qwik/act-list.rb +287 -0
  52. data/vendor/qwik/act-login.rb +410 -0
  53. data/vendor/qwik/act-logout.rb +60 -0
  54. data/vendor/qwik/act-mail.rb +159 -0
  55. data/vendor/qwik/act-map.rb +292 -0
  56. data/vendor/qwik/act-md5.rb +42 -0
  57. data/vendor/qwik/act-mdlb.rb +741 -0
  58. data/vendor/qwik/act-media.rb +416 -0
  59. data/vendor/qwik/act-member.rb +157 -0
  60. data/vendor/qwik/act-menu.rb +142 -0
  61. data/vendor/qwik/act-metadata.rb +323 -0
  62. data/vendor/qwik/act-mlsubmitform.rb +49 -0
  63. data/vendor/qwik/act-monitor.rb +167 -0
  64. data/vendor/qwik/act-new.rb +418 -0
  65. data/vendor/qwik/act-pagelist.rb +248 -0
  66. data/vendor/qwik/act-password.rb +145 -0
  67. data/vendor/qwik/act-plan.rb +210 -0
  68. data/vendor/qwik/act-povray.rb +230 -0
  69. data/vendor/qwik/act-presen.rb +380 -0
  70. data/vendor/qwik/act-redirect.rb +133 -0
  71. data/vendor/qwik/act-ring.rb +1071 -0
  72. data/vendor/qwik/act-rrefs.rb +255 -0
  73. data/vendor/qwik/act-ruby.rb +116 -0
  74. data/vendor/qwik/act-sample.rb +170 -0
  75. data/vendor/qwik/act-save.rb +295 -0
  76. data/vendor/qwik/act-schedule.rb +374 -0
  77. data/vendor/qwik/act-search.rb +180 -0
  78. data/vendor/qwik/act-searchwords.rb +51 -0
  79. data/vendor/qwik/act-sendpass.rb +83 -0
  80. data/vendor/qwik/act-site.rb +89 -0
  81. data/vendor/qwik/act-sitebackup.rb +419 -0
  82. data/vendor/qwik/act-sitelog.rb +118 -0
  83. data/vendor/qwik/act-smil.rb +299 -0
  84. data/vendor/qwik/act-status.rb +220 -0
  85. data/vendor/qwik/act-style.rb +608 -0
  86. data/vendor/qwik/act-table.rb +263 -0
  87. data/vendor/qwik/act-tableform.rb +241 -0
  88. data/vendor/qwik/act-tag.rb +103 -0
  89. data/vendor/qwik/act-text.rb +70 -0
  90. data/vendor/qwik/act-textarea.rb +164 -0
  91. data/vendor/qwik/act-theme.rb +346 -0
  92. data/vendor/qwik/act-toc.rb +112 -0
  93. data/vendor/qwik/act-typekey.rb +198 -0
  94. data/vendor/qwik/act-under-const.rb +94 -0
  95. data/vendor/qwik/act-webservice.rb +321 -0
  96. data/vendor/qwik/act-wema.rb +558 -0
  97. data/vendor/qwik/act-wysiwyg.rb +238 -0
  98. data/vendor/qwik/action.rb +325 -0
  99. data/vendor/qwik/autoreload.rb +98 -0
  100. data/vendor/qwik/bench-bench.rb +28 -0
  101. data/vendor/qwik/bench-emode.rb +47 -0
  102. data/vendor/qwik/bench-format-xml.rb +70 -0
  103. data/vendor/qwik/bench-large-table.rb +62 -0
  104. data/vendor/qwik/bench-md5.rb +14 -0
  105. data/vendor/qwik/bench-module-session.rb +19 -0
  106. data/vendor/qwik/bench-page.rb +50 -0
  107. data/vendor/qwik/bench-s-md5.rb +28 -0
  108. data/vendor/qwik/bench-session.rb +25 -0
  109. data/vendor/qwik/bench-textformat.rb +31 -0
  110. data/vendor/qwik/catalog-factory.rb +91 -0
  111. data/vendor/qwik/catalog-ja.rb +479 -0
  112. data/vendor/qwik/catalog-ml-ja.rb +145 -0
  113. data/vendor/qwik/check-act-monitor.rb +112 -0
  114. data/vendor/qwik/check-act-monitor2.rb +46 -0
  115. data/vendor/qwik/check-act-theme.rb +27 -0
  116. data/vendor/qwik/check-event.rb +112 -0
  117. data/vendor/qwik/check-event2.rb +55 -0
  118. data/vendor/qwik/check-htree-rexml.rb +77 -0
  119. data/vendor/qwik/check-htree.rb +51 -0
  120. data/vendor/qwik/check-libxml.rb +135 -0
  121. data/vendor/qwik/check-many-pages.rb +47 -0
  122. data/vendor/qwik/check-monitor.rb +33 -0
  123. data/vendor/qwik/check-observer.rb +67 -0
  124. data/vendor/qwik/check-server.rb +61 -0
  125. data/vendor/qwik/check-uuencode.rb +33 -0
  126. data/vendor/qwik/check-webdav.rb +65 -0
  127. data/vendor/qwik/check-xml-xpath.rb +27 -0
  128. data/vendor/qwik/common-backtrace.rb +94 -0
  129. data/vendor/qwik/common-basic.rb +111 -0
  130. data/vendor/qwik/common-condition.rb +142 -0
  131. data/vendor/qwik/common-error.rb +48 -0
  132. data/vendor/qwik/common-gettext.rb +50 -0
  133. data/vendor/qwik/common-javascript.rb +45 -0
  134. data/vendor/qwik/common-notice.rb +132 -0
  135. data/vendor/qwik/common-plain.rb +105 -0
  136. data/vendor/qwik/common-plugin.rb +111 -0
  137. data/vendor/qwik/common-res.rb +76 -0
  138. data/vendor/qwik/common-resolve.rb +92 -0
  139. data/vendor/qwik/common-send.rb +171 -0
  140. data/vendor/qwik/common-session.rb +139 -0
  141. data/vendor/qwik/common-surface.rb +261 -0
  142. data/vendor/qwik/common-url.rb +90 -0
  143. data/vendor/qwik/compat/Makefile +12 -0
  144. data/vendor/qwik/compat/add_load_path.rb +1 -0
  145. data/vendor/qwik/config.rb +299 -0
  146. data/vendor/qwik/db-b-backup.rb +142 -0
  147. data/vendor/qwik/db-backup.rb +184 -0
  148. data/vendor/qwik/db-berkeley.rb +306 -0
  149. data/vendor/qwik/db-filesystem.rb +305 -0
  150. data/vendor/qwik/db-indexer.rb +154 -0
  151. data/vendor/qwik/db-searchwords.rb +238 -0
  152. data/vendor/qwik/description-ja.rb +267 -0
  153. data/vendor/qwik/description.rb +256 -0
  154. data/vendor/qwik/dev-add-copyright.rb +23 -0
  155. data/vendor/qwik/dev-backup.rb +24 -0
  156. data/vendor/qwik/dev-bench.rb +175 -0
  157. data/vendor/qwik/dev-calctime.rb +52 -0
  158. data/vendor/qwik/dev-css-compressor.rb +60 -0
  159. data/vendor/qwik/dev-extract-catalog.rb +102 -0
  160. data/vendor/qwik/dev-js-compressor.rb +73 -0
  161. data/vendor/qwik/dev-release.rb +235 -0
  162. data/vendor/qwik/dev-replace.rb +353 -0
  163. data/vendor/qwik/dev-sendmail.rb +25 -0
  164. data/vendor/qwik/farm.rb +283 -0
  165. data/vendor/qwik/gettext.rb +56 -0
  166. data/vendor/qwik/group-cond.rb +157 -0
  167. data/vendor/qwik/group-config.rb +247 -0
  168. data/vendor/qwik/group-confirm.rb +147 -0
  169. data/vendor/qwik/group-db.rb +326 -0
  170. data/vendor/qwik/group-mail.rb +195 -0
  171. data/vendor/qwik/group-member.rb +307 -0
  172. data/vendor/qwik/group-sendmail.rb +231 -0
  173. data/vendor/qwik/group-site.rb +374 -0
  174. data/vendor/qwik/group-sweep.rb +63 -0
  175. data/vendor/qwik/group.rb +157 -0
  176. data/vendor/qwik/helper.rb +6 -0
  177. data/vendor/qwik/html-generator.rb +104 -0
  178. data/vendor/qwik/html-to-wabisabi.rb +149 -0
  179. data/vendor/qwik/htree-diff.rb +87 -0
  180. data/vendor/qwik/htree-format-xml.rb +57 -0
  181. data/vendor/qwik/htree-generator.rb +144 -0
  182. data/vendor/qwik/htree-get.rb +251 -0
  183. data/vendor/qwik/htree-html-generator.rb +179 -0
  184. data/vendor/qwik/htree-template.rb +263 -0
  185. data/vendor/qwik/htree-to-wabisabi.rb +171 -0
  186. data/vendor/qwik/loadlib.rb +79 -0
  187. data/vendor/qwik/logger.rb +115 -0
  188. data/vendor/qwik/mail-body.rb +171 -0
  189. data/vendor/qwik/mail-header.rb +474 -0
  190. data/vendor/qwik/mail-multipart.rb +193 -0
  191. data/vendor/qwik/mail-parse.rb +147 -0
  192. data/vendor/qwik/mail.rb +341 -0
  193. data/vendor/qwik/mailaddress.rb +83 -0
  194. data/vendor/qwik/mdlb-model.rb +81 -0
  195. data/vendor/qwik/mdlb-sample.rb +324 -0
  196. data/vendor/qwik/ml-catalog-factory.rb +27 -0
  197. data/vendor/qwik/ml-exception.rb +15 -0
  198. data/vendor/qwik/ml-generator.rb +28 -0
  199. data/vendor/qwik/ml-gettext.rb +137 -0
  200. data/vendor/qwik/ml-logger.rb +82 -0
  201. data/vendor/qwik/ml-memory.rb +65 -0
  202. data/vendor/qwik/ml-msg-validator.rb +86 -0
  203. data/vendor/qwik/ml-processor.rb +609 -0
  204. data/vendor/qwik/ml-quickml-server.rb +122 -0
  205. data/vendor/qwik/ml-sendmail.rb +0 -0
  206. data/vendor/qwik/ml-server.rb +107 -0
  207. data/vendor/qwik/ml-session.rb +348 -0
  208. data/vendor/qwik/ml-sweeper.rb +101 -0
  209. data/vendor/qwik/mock-logger.rb +65 -0
  210. data/vendor/qwik/mock-sendmail.rb +78 -0
  211. data/vendor/qwik/mock-socket.rb +82 -0
  212. data/vendor/qwik/modulobe.rb +406 -0
  213. data/vendor/qwik/mongrel-server.rb +72 -0
  214. data/vendor/qwik/page-files.rb +249 -0
  215. data/vendor/qwik/page-generate.rb +82 -0
  216. data/vendor/qwik/page-get.rb +262 -0
  217. data/vendor/qwik/page-images.rb +168 -0
  218. data/vendor/qwik/page-put.rb +128 -0
  219. data/vendor/qwik/page-rrefs.rb +154 -0
  220. data/vendor/qwik/page-title.rb +0 -0
  221. data/vendor/qwik/page-wikidb.rb +234 -0
  222. data/vendor/qwik/page.rb +67 -0
  223. data/vendor/qwik/pages.rb +444 -0
  224. data/vendor/qwik/parse-plugin.rb +249 -0
  225. data/vendor/qwik/parser-emode.rb +116 -0
  226. data/vendor/qwik/parser-inline.rb +273 -0
  227. data/vendor/qwik/parser.rb +350 -0
  228. data/vendor/qwik/password.rb +183 -0
  229. data/vendor/qwik/periodic.rb +79 -0
  230. data/vendor/qwik/qp.rb +56 -0
  231. data/vendor/qwik/qwik-service.rb +341 -0
  232. data/vendor/qwik/qwik.rb +5 -0
  233. data/vendor/qwik/qwikweb-adduser.rb +34 -0
  234. data/vendor/qwik/qwikweb-catalog-validator.rb +110 -0
  235. data/vendor/qwik/qwikweb-incgen.rb +28 -0
  236. data/vendor/qwik/qwikweb-makesite.rb +41 -0
  237. data/vendor/qwik/qwikweb-server.rb +44 -0
  238. data/vendor/qwik/qwikweb-showpassword.rb +26 -0
  239. data/vendor/qwik/qwikweb-watchlog.rb +67 -0
  240. data/vendor/qwik/request-path.rb +304 -0
  241. data/vendor/qwik/request-ua.rb +76 -0
  242. data/vendor/qwik/request-webrick.rb +81 -0
  243. data/vendor/qwik/request.rb +91 -0
  244. data/vendor/qwik/resolve-tdiary.rb +292 -0
  245. data/vendor/qwik/resolve.rb +121 -0
  246. data/vendor/qwik/response.rb +228 -0
  247. data/vendor/qwik/server-memory.rb +57 -0
  248. data/vendor/qwik/server-webrick.rb +102 -0
  249. data/vendor/qwik/server.rb +252 -0
  250. data/vendor/qwik/site-config.rb +149 -0
  251. data/vendor/qwik/site-db.rb +136 -0
  252. data/vendor/qwik/site-event.rb +162 -0
  253. data/vendor/qwik/site-files.rb +86 -0
  254. data/vendor/qwik/site-group.rb +103 -0
  255. data/vendor/qwik/site-index.rb +47 -0
  256. data/vendor/qwik/site-log.rb +64 -0
  257. data/vendor/qwik/site-member.rb +230 -0
  258. data/vendor/qwik/site-monitor.rb +97 -0
  259. data/vendor/qwik/site-pages.rb +62 -0
  260. data/vendor/qwik/site-plan.rb +139 -0
  261. data/vendor/qwik/site-report.rb +282 -0
  262. data/vendor/qwik/site-resolve.rb +230 -0
  263. data/vendor/qwik/site-rrefs.rb +18 -0
  264. data/vendor/qwik/site-search.rb +180 -0
  265. data/vendor/qwik/site-timeline.rb +153 -0
  266. data/vendor/qwik/site-url.rb +189 -0
  267. data/vendor/qwik/site.rb +76 -0
  268. data/vendor/qwik/smil-time.rb +105 -0
  269. data/vendor/qwik/smtp-session.rb +331 -0
  270. data/vendor/qwik/template-generator.rb +149 -0
  271. data/vendor/qwik/template.rb +85 -0
  272. data/vendor/qwik/test-common.rb +10 -0
  273. data/vendor/qwik/test-ml-info.rb +225 -0
  274. data/vendor/qwik/test-module-ml.rb +142 -0
  275. data/vendor/qwik/test-module-path.rb +110 -0
  276. data/vendor/qwik/test-module-public.rb +70 -0
  277. data/vendor/qwik/test-module-server.rb +98 -0
  278. data/vendor/qwik/test-module-session.rb +264 -0
  279. data/vendor/qwik/test-module-suite.rb +91 -0
  280. data/vendor/qwik/test-ms-applemail.rb +59 -0
  281. data/vendor/qwik/test-ms-attach.rb +174 -0
  282. data/vendor/qwik/test-ms-basic.rb +40 -0
  283. data/vendor/qwik/test-ms-close.rb +35 -0
  284. data/vendor/qwik/test-ms-confirm.rb +75 -0
  285. data/vendor/qwik/test-ms-ignore-spam.rb +57 -0
  286. data/vendor/qwik/test-ms-japanese.rb +97 -0
  287. data/vendor/qwik/test-ms-jfilename.rb +82 -0
  288. data/vendor/qwik/test-ms-large.rb +58 -0
  289. data/vendor/qwik/test-ms-member.rb +103 -0
  290. data/vendor/qwik/test-ms-multipart.rb +84 -0
  291. data/vendor/qwik/test-ms-org.rb +129 -0
  292. data/vendor/qwik/test-ms-plan.rb +130 -0
  293. data/vendor/qwik/test-ms-post.rb +53 -0
  294. data/vendor/qwik/test-ms-quopri.rb +76 -0
  295. data/vendor/qwik/test-sub-quopri.rb +45 -0
  296. data/vendor/qwik/test-submit-base64.rb +59 -0
  297. data/vendor/qwik/test-submit-forward.rb +61 -0
  298. data/vendor/qwik/test-submit-html-mail.rb +52 -0
  299. data/vendor/qwik/test-submit-japanese.rb +135 -0
  300. data/vendor/qwik/test-submit-jfilename.rb +144 -0
  301. data/vendor/qwik/test-submit-uuencode.rb +71 -0
  302. data/vendor/qwik/test-suite-all.rb +8 -0
  303. data/vendor/qwik/test-suite-basic.rb +9 -0
  304. data/vendor/qwik/test-suite-ml.rb +9 -0
  305. data/vendor/qwik/test-typekey.rb +64 -0
  306. data/vendor/qwik/testunit.rb +45 -0
  307. data/vendor/qwik/tokenizer-inline.rb +294 -0
  308. data/vendor/qwik/tokenizer.rb +332 -0
  309. data/vendor/qwik/typekey.rb +160 -0
  310. data/vendor/qwik/util-basic.rb +135 -0
  311. data/vendor/qwik/util-charset.rb +332 -0
  312. data/vendor/qwik/util-css.rb +56 -0
  313. data/vendor/qwik/util-csv-tokenizer.rb +113 -0
  314. data/vendor/qwik/util-filename.rb +112 -0
  315. data/vendor/qwik/util-pathname.rb +202 -0
  316. data/vendor/qwik/util-pid.rb +58 -0
  317. data/vendor/qwik/util-safe.rb +67 -0
  318. data/vendor/qwik/util-sendmail.rb +273 -0
  319. data/vendor/qwik/util-string.rb +203 -0
  320. data/vendor/qwik/util-time.rb +125 -0
  321. data/vendor/qwik/util-webrick.rb +176 -0
  322. data/vendor/qwik/version.rb +11 -0
  323. data/vendor/qwik/wabisabi-basic.rb +163 -0
  324. data/vendor/qwik/wabisabi-diff.rb +130 -0
  325. data/vendor/qwik/wabisabi-format-xml.rb +310 -0
  326. data/vendor/qwik/wabisabi-generator.rb +262 -0
  327. data/vendor/qwik/wabisabi-index.rb +174 -0
  328. data/vendor/qwik/wabisabi-table.rb +212 -0
  329. data/vendor/qwik/wabisabi-template.rb +295 -0
  330. data/vendor/qwik/wabisabi-to-htree.rb +111 -0
  331. data/vendor/qwik/wabisabi-to-wiki.rb +690 -0
  332. data/vendor/qwik/wabisabi-traverse.rb +207 -0
  333. data/vendor/qwik/wabisabi-validator.rb +116 -0
  334. data/vendor/qwik/wabisabi.rb +5 -0
  335. metadata +416 -0
@@ -0,0 +1,142 @@
1
+ # Copyright (C) 2003-2006 Kouichirou Eto, All rights reserved.
2
+ # This is free software with ABSOLUTELY NO WARRANTY.
3
+ # You can redistribute it and/or modify it under the terms of the GNU GPL 2.
4
+
5
+ $LOAD_PATH.unshift '..' unless $LOAD_PATH.include? '..'
6
+ require 'pathname'
7
+ require 'qwik/db-berkeley'
8
+
9
+ module Qwik
10
+ class BackupBDB
11
+ def initialize(path)
12
+ @backup_path = path+'.backup'
13
+ @db = open_db(path+'backup.db')
14
+ end
15
+
16
+ def open_db(path)
17
+ options = 0
18
+ unless path.exist? # don't over write
19
+ options = BDB::CREATE | BDB::EXCL
20
+ end
21
+ db = BDB::Hash.open(path.to_s, nil, options)
22
+ return db
23
+ end
24
+
25
+ def close
26
+ @db.close
27
+ end
28
+
29
+ def path(k, time) # k is String, t is Time
30
+ t = time.to_i.to_s
31
+ @backup_path+(t+'_'+k)
32
+ end
33
+ private :path
34
+
35
+ def exist?(k, time)
36
+ v = db_get(k, time)
37
+ return true if v
38
+ path(k, time).exist?
39
+ end
40
+
41
+ def get(k, time)
42
+ v = db_get(k, time)
43
+ return v if v
44
+ if path(k, time).exist?
45
+ str = path(k, time).open {|f| f.read }
46
+ put(k, time, v)
47
+ return str
48
+ end
49
+ ''
50
+ end
51
+
52
+ def db_get(k, time)
53
+ @db.get(make_key(k, time))
54
+ end
55
+
56
+ def make_key(k, time)
57
+ k+','+time.to_i.to_s
58
+ end
59
+ private :db_get, :make_key
60
+
61
+ def put(k, time, v)
62
+ @db.put(make_key(k, time), v)
63
+ end
64
+ alias set put
65
+
66
+ def each_by_key(key)
67
+ ar = []
68
+ # FIXME: use each_by_prefix(key+',') instead
69
+ @db.each {|k, v|
70
+ next if v.nil?
71
+ if /\A#{key},([0-9]+)\z/ =~ k # begin with key?
72
+ time = Time.at($1.to_i)
73
+ ar << [v, time]
74
+ end
75
+ }
76
+
77
+ if @backup_path.exist?
78
+ @backup_path.each_entry {|file|
79
+ f = @backup_path+file
80
+ next unless f.file?
81
+ base = file.to_s
82
+ if /\A([0-9]+)_#{key}\z/ =~ base # end with key ?
83
+ time = Time.at($1.to_i)
84
+ v = get(key, time)
85
+ ar << [v, time]
86
+ end
87
+ }
88
+ end
89
+
90
+ ar.sort_by {|v, time|
91
+ time
92
+ }.each {|v, time|
93
+ yield(v, time)
94
+ }
95
+ end
96
+ end
97
+ end
98
+
99
+ if $0 == __FILE__
100
+ require 'qwik/testunit'
101
+ require 'qwik/config'
102
+ require 'qwik/test-module-path'
103
+ $test = true
104
+ end
105
+
106
+ if defined?($test) && $test
107
+ class TestBackupBDB < Test::Unit::TestCase
108
+ def setup
109
+ @config = Qwik::Config.new
110
+ @config[:db] = 'bdb'
111
+ @dir = 'test/'.path
112
+ @dir.setup
113
+ path = @dir
114
+ spath = @config.super_dir.path
115
+ @pagedb = Qwik::BerkeleyDB.new(path, spath)
116
+ end
117
+
118
+ def teardown
119
+ @pagedb.close if @pagedb
120
+ @dir.teardown
121
+ end
122
+
123
+ def test_backupdb
124
+ @pagedb.create('1')
125
+ @pagedb.put('1', 't', Time.at(1))
126
+
127
+ budb = @pagedb.backupdb
128
+ assert_instance_of(Qwik::BackupBDB, budb)
129
+
130
+ budb.each_by_key('1') {|v, time|
131
+ assert_instance_of(String, v)
132
+ assert_instance_of(Time, time)
133
+ s = budb.get('1', time)
134
+ assert_instance_of(String, s)
135
+ eq v, s
136
+ }
137
+
138
+ #put
139
+ #exist?
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,184 @@
1
+ # Copyright (C) 2003-2006 Kouichirou Eto, All rights reserved.
2
+ # This is free software with ABSOLUTELY NO WARRANTY.
3
+ # You can redistribute it and/or modify it under the terms of the GNU GPL 2.
4
+
5
+ $LOAD_PATH.unshift '..' unless $LOAD_PATH.include? '..'
6
+ require 'qwik/util-pathname'
7
+
8
+ module Qwik
9
+ class BackupDB
10
+ include Enumerable
11
+
12
+ def initialize(path)
13
+ @backup_path = path+'.backup'
14
+ end
15
+
16
+ def close
17
+ # do nothing
18
+ end
19
+
20
+ def path(k, time) # k: String, t: Time
21
+ t = time.to_i.to_s
22
+ return @backup_path+"#{t}_#{k}"
23
+ end
24
+ private :path
25
+
26
+ def exist?(k, time)
27
+ return path(k, time).exist?
28
+ end
29
+
30
+ def get(k, time)
31
+ return path(k, time).read
32
+ end
33
+
34
+ def check(k, v)
35
+ end
36
+
37
+ IGNORE_PAGES = [
38
+ /\A_SiteLog\Z/,
39
+ /\A_SiteChanged\Z/,
40
+ /\A_GroupCharset\Z/,
41
+ /\A_GroupCount\Z/,
42
+ /\A_counter_[_A-Za-z0-9]+\Z/
43
+ ]
44
+
45
+ def put(k, v, time)
46
+ @backup_path.check_directory
47
+ return if IGNORE_PAGES.any? {|re| re =~ k }
48
+ path(k, time).put(v)
49
+ end
50
+ alias set put
51
+
52
+ def each_by_key(key)
53
+ each {|k, v, time|
54
+ yield(v, time) if k == key
55
+ }
56
+ end
57
+
58
+ def each
59
+ @backup_path.check_directory
60
+ ar = []
61
+ @backup_path.each_entry {|file|
62
+ f = @backup_path+file
63
+ next unless f.file?
64
+ base = file.to_s
65
+ if /\A([0-9]+)_([_A-Za-z0-9]+)\z/ =~ base
66
+ time = Time.at($1.to_i)
67
+ key = $2
68
+ ar << [key, time]
69
+ end
70
+ }
71
+
72
+ ar.sort_by {|key, time|
73
+ time
74
+ }.each {|key, time|
75
+ # v = get(key, time)
76
+ v = "" # FIXME: This is dummy. 2009/9/1
77
+ yield(key, v, time)
78
+ }
79
+ end
80
+ end
81
+ end
82
+
83
+ if $0 == __FILE__
84
+ require 'qwik/testunit'
85
+ require 'qwik/config'
86
+ require 'qwik/test-module-path'
87
+ require 'qwik/db-filesystem'
88
+ $test = true
89
+ end
90
+
91
+ if defined?($test) && $test
92
+ class TestBackupDB < Test::Unit::TestCase
93
+ def setup
94
+ config = Qwik::Config.new
95
+ config.update Qwik::Config::DebugConfig
96
+ config.update Qwik::Config::TestConfig
97
+ @path = '.test/'.path
98
+ @path.setup
99
+
100
+ spath = config.super_dir.path
101
+ @pagedb = Qwik::FileSystemDB.new(@path, spath)
102
+
103
+ # test_initialize
104
+ backupdb = Qwik::BackupDB.new(@path)
105
+ @pagedb.register_observer(backupdb)
106
+ end
107
+
108
+ def test_backupdb
109
+ # test_put
110
+ @pagedb.create('1')
111
+ @pagedb.put('1', 't', 1)
112
+
113
+ budb = @pagedb.backupdb
114
+ assert_instance_of(Qwik::BackupDB, budb)
115
+
116
+ # test_each_by_key
117
+ budb.each_by_key('1') {|v, time|
118
+ assert_instance_of(String, v)
119
+ assert_instance_of(Time, time)
120
+ s = budb.get('1', time)
121
+ assert_instance_of(String, s)
122
+ # eq v, s
123
+ }
124
+
125
+ # FIXME: test_put, test_exist should be exist.
126
+ end
127
+
128
+ def test_ignore_pages
129
+ key = '_SiteLog'
130
+ @pagedb.create(key)
131
+ @pagedb.put(key, 't', 1)
132
+
133
+ # test_each_by_key
134
+ found = false
135
+ @pagedb.backupdb.each_by_key(key) {|v, time|
136
+ found = true
137
+ }
138
+ assert_equal false, found
139
+ end
140
+
141
+ def test_ignore_pages2
142
+ key = '_counter_1'
143
+ @pagedb.create(key)
144
+ @pagedb.put(key, 't', 1)
145
+
146
+ # test_each_by_key
147
+ found = false
148
+ @pagedb.backupdb.each_by_key(key) {|v, time|
149
+ found = true
150
+ }
151
+ assert_equal false, found
152
+ end
153
+
154
+ def test_ignore_pages3
155
+ key = '_counter_'
156
+ @pagedb.create(key)
157
+ @pagedb.put(key, 't', 1)
158
+
159
+ # test_each_by_key
160
+ found = false
161
+ @pagedb.backupdb.each_by_key(key) {|v, time|
162
+ found = true
163
+ }
164
+ assert_equal true, found
165
+ end
166
+
167
+ def test_ignore_pages4
168
+ key = '_SiteLogHoge'
169
+ @pagedb.create(key)
170
+ @pagedb.put(key, 't', 1)
171
+
172
+ # test_each_by_key
173
+ found = false
174
+ @pagedb.backupdb.each_by_key(key) {|v, time|
175
+ found = true
176
+ }
177
+ assert_equal true, found
178
+ end
179
+
180
+ def teardown
181
+ @path.teardown
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,306 @@
1
+ # Copyright (C) 2003-2006 Kouichirou Eto, All rights reserved.
2
+ # This is free software with ABSOLUTELY NO WARRANTY.
3
+ # You can redistribute it and/or modify it under the terms of the GNU GPL 2.
4
+
5
+ begin
6
+ require 'bdb'
7
+ $have_bdb_so = true
8
+ rescue LoadError
9
+ $have_bdb_so = false
10
+ end
11
+
12
+ $LOAD_PATH.unshift '..' unless $LOAD_PATH.include? '..'
13
+ require 'qwik/util-pathname'
14
+ require 'qwik/db-b-backup'
15
+
16
+ module Qwik
17
+ class BerkeleyDB
18
+ include Enumerable
19
+
20
+ def initialize(path, spath)
21
+ @path = path
22
+ raise 'No such dir. '+@path.to_s unless @path.directory?
23
+ @path_h = {}
24
+ @spath = spath
25
+ @spath_h = {}
26
+
27
+ @db = open_db(@path+'pages.db')
28
+ @mtime_db = open_db(@path+'mtime.db')
29
+
30
+ @backupdb = BackupBDB.new(@path)
31
+ end
32
+ attr_reader :backupdb
33
+
34
+ def open_db(path)
35
+ options = 0
36
+ options = BDB::CREATE | BDB::EXCL unless path.exist? # don't over write
37
+ begin
38
+ db = BDB::Hash.open(path.to_s, nil, options)
39
+ rescue => e
40
+ p 'e is '+e
41
+ @path.each_entry {|pa|
42
+ if /\.db\z/ =~ pa.to_s
43
+ p pa
44
+ (@path+pa).unlink
45
+ end
46
+ }
47
+ $try ||= 0
48
+ $try += 1
49
+ retry if $try < 5
50
+ raise e
51
+ end
52
+ return db
53
+ end
54
+
55
+ def close
56
+ @backupdb.close
57
+ @db.close
58
+ @mtime_db.close
59
+ end
60
+
61
+ def exist?(k)
62
+ begin
63
+ return true if baseexist?(k)
64
+ return true if spath(k).exist?
65
+ rescue
66
+ return false
67
+ end
68
+ return false
69
+ end
70
+
71
+ def baseexist?(k)
72
+ v = db_get(k)
73
+ return true if v
74
+ begin
75
+ return true if path(k).exist?
76
+ rescue
77
+ return false
78
+ end
79
+ return false
80
+ end
81
+
82
+ def create(k)
83
+ touch(k) unless exist?(k)
84
+ end
85
+
86
+ def get(k)
87
+ v = db_get(k)
88
+ return v if v
89
+ if path(k).exist?
90
+ str = path(k).get
91
+ mtime = path(k).mtime
92
+ db_put(k, str, mtime)
93
+ return str
94
+ end
95
+ return spath(k).get if spath(k).exist?
96
+ ''
97
+ end
98
+
99
+ def db_get(k)
100
+ begin
101
+ @db.get(k)
102
+ rescue BDB::Fatal => e
103
+ return if e.message == 'closed DB'
104
+ raise e
105
+ end
106
+ end
107
+
108
+ def mtime(k)
109
+ v = db_get(k)
110
+ if v
111
+ num = @mtime_db.get(k)
112
+ return Time.at(num.to_i)
113
+ end
114
+ return path(k).mtime if path(k).exist?
115
+ return spath(k).mtime if spath(k).exist?
116
+ Time.at(0) # the file is already deleted.
117
+ end
118
+
119
+ def add(k, v, time=Time.now)
120
+ # FIXME: use @db.add(k, v) instead
121
+ put(k, get(k)+v, time)
122
+ end
123
+
124
+ def put(k, v, time=Time.now)
125
+ db_put(k, v, time)
126
+ @backupdb.put(k, time, v)
127
+ path(k).open('wb'){|f| f.print(v) } # write through
128
+ end
129
+ alias set put
130
+
131
+ def db_put(k, v, mtime)
132
+ @db.put(k, v)
133
+ @mtime_db.put(k, mtime.to_i.to_s)
134
+ end
135
+
136
+ def touch(k)
137
+ add(k, '') # add null String
138
+ end
139
+
140
+ def delete(k)
141
+ put(k, nil)
142
+ path(k).unlink if path(k).exist?
143
+ end
144
+
145
+ def each
146
+ ar = []
147
+ @db.each {|k, v|
148
+ next if v.nil?
149
+ ar << k
150
+ }
151
+ dir = @path.to_s
152
+ Dir.foreach(dir) {|file|
153
+ f = dir+'/'+file
154
+ next unless FileTest.file?(f)
155
+ base = file.to_s
156
+ if /\A([_A-Za-z0-9]+)\.txt\z/ =~ base
157
+ b = $1
158
+ ar << b if !ar.include?(b)
159
+ end
160
+ }
161
+ ar.sort.each {|k|
162
+ yield(k)
163
+ }
164
+ end
165
+
166
+ def last_page_time # mtime of the newest page
167
+ t = map {|k| mtime(k) }.max
168
+ t = Time.at(0) if t.nil?
169
+ t
170
+ end
171
+
172
+ # QuickML support
173
+ def last_article_time # mtime of the newest file
174
+ max = maxfile = nil
175
+ @path.each_entry {|file|
176
+ f = @path+file
177
+ next unless f.file?
178
+ base = file.to_s
179
+ next if /\A\./ =~ base ||
180
+ base == ',config' ||
181
+ base == '_GroupConfig.txt' ||
182
+ base == ',charset' ||
183
+ base == '_GroupCharset.txt'
184
+ next if /\.db\z/ =~ base
185
+ mt = f.mtime
186
+ if max.nil? || max < mt
187
+ max = mt
188
+ maxfile = f
189
+ end
190
+ }
191
+ max # return nil if there is no file.
192
+ end
193
+
194
+ private
195
+
196
+ def path(k)
197
+ gen_path(@path, @path_h, k)
198
+ end
199
+
200
+ def spath(k)
201
+ gen_path(@spath, @spath_h, k)
202
+ end
203
+
204
+ def gen_path(path, h, k)
205
+ pa = h[k]
206
+ return pa if pa
207
+ raise 'Character type error '+k unless /\A([_A-Za-z0-9]+)\z/ =~ k
208
+ h[k] = path+(k+'.txt')
209
+ h[k]
210
+ end
211
+ end
212
+ end
213
+
214
+ if $0 == __FILE__
215
+ require 'qwik/testunit'
216
+ require 'qwik/config'
217
+ require 'qwik/farm'
218
+ require 'qwik/server-memory'
219
+ require 'qwik/test-module-session'
220
+ $test = true
221
+ end
222
+
223
+ if defined?($test) && $test
224
+ class TestBerkeleyDB < Test::Unit::TestCase
225
+ include TestSession
226
+
227
+ def test_bdb
228
+ @pagedb = @site.db
229
+
230
+ ok_eq(false, @pagedb.exist?('1'))
231
+
232
+ @pagedb.create('1')
233
+ ok_eq(true, @pagedb.exist?('1'))
234
+ ok_eq('', @pagedb.get('1'))
235
+
236
+ @pagedb.put('1', 't')
237
+ ok_eq('t', @pagedb.get('1'))
238
+
239
+ assert_instance_of(Time, @pagedb.mtime('1'))
240
+
241
+ @pagedb.add('1', 's')
242
+ ok_eq('ts', @pagedb.get('1'))
243
+
244
+ assert_instance_of(Time, @pagedb.last_page_time)
245
+
246
+ assert_instance_of(Time, @pagedb.last_article_time)
247
+
248
+ @pagedb.each {|f|
249
+ assert_instance_of(String, f)
250
+ }
251
+
252
+ @pagedb.touch('1')
253
+
254
+ @pagedb.delete('1')
255
+ ok_eq(false, @pagedb.exist?('1'))
256
+
257
+ # page = @pagedb.db_get('1') # db_get should be private.
258
+ # ok_eq(nil, page)
259
+ # page = @pagedb.get('1')
260
+ # ok_eq('', page)
261
+
262
+ @pagedb.touch('1')
263
+ ok_eq(true, @pagedb.exist?('1'))
264
+
265
+ @pagedb.delete('1')
266
+ ok_eq(false, @pagedb.exist?('1'))
267
+
268
+ ok_eq(true, @pagedb.exist?('_SideMenu'))
269
+ ok_eq(false, @pagedb.baseexist?('_SideMenu'))
270
+
271
+ # test_not_exist
272
+ @pagedb = @site.db
273
+
274
+ ok_eq(false, @pagedb.exist?('1'))
275
+
276
+ @pagedb.put('1', 't')
277
+ ok_eq(true, @pagedb.exist?('1'))
278
+
279
+ # test_super_files
280
+ @pagedb = @site.db
281
+
282
+ page = @site['_SiteConfig']
283
+ assert_match(/theme/, page.get)
284
+
285
+ @dir.erase_all_for_test
286
+
287
+ page = @site['_SiteConfig']
288
+ assert_match(/theme/, page.get)
289
+ end
290
+ end
291
+
292
+ class CheckBerkeleyDB < Test::Unit::TestCase
293
+ def test_bdb
294
+ return if $0 != __FILE__ # Only for separated test.
295
+
296
+ path = 'test.db'.path
297
+ path.unlink if path.exist?
298
+ options = BDB::CREATE | BDB::EXCL # Do not over write.
299
+ db = BDB::Hash.open(path.to_s, nil, options)
300
+ db.put('1', 't')
301
+ ok_eq('t', db.get('1'))
302
+ db.close
303
+ path.unlink if path.exist?
304
+ end
305
+ end
306
+ end