nosql-tutorial 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. data/README.markdown +20 -0
  2. data/Rakefile +34 -0
  3. data/VERSION.yml +5 -0
  4. data/lib/config.ru +12 -0
  5. data/lib/nosql.rb +64 -0
  6. data/lib/public/doc/mail/body.txt +1 -0
  7. data/lib/public/doc/mail/mail-00.rb +31 -0
  8. data/lib/public/doc/mail/mail-01.rb +29 -0
  9. data/lib/public/doc/mail/mail-10.rb +24 -0
  10. data/lib/public/doc/mail/motylek.jpeg +0 -0
  11. data/lib/public/doc/plain-text-files/contacts.yaml +11 -0
  12. data/lib/public/doc/plain-text-files/contacts_g.rb +105 -0
  13. data/lib/public/doc/plain-text-files/contacts_g_test.rb +51 -0
  14. data/lib/public/doc/plain-text-files/contacts_y.rb +57 -0
  15. data/lib/public/doc/plain-text-files/contacts_y_test.rb +39 -0
  16. data/lib/public/doc/plain-text-files/gdbm-example.rb +22 -0
  17. data/lib/public/doc/using-plain-text-files-for-data-persistence.pdf +0 -0
  18. data/lib/public/favicon.ico +0 -0
  19. data/lib/public/images/conan_doyle.jpg +0 -0
  20. data/lib/public/images/datamapper.png +0 -0
  21. data/lib/public/images/datamapper.svg +95 -0
  22. data/lib/public/stylesheets/fonts/Cyklop-Italic.otf +0 -0
  23. data/lib/public/stylesheets/icons/cross.png +0 -0
  24. data/lib/public/stylesheets/icons/doc.png +0 -0
  25. data/lib/public/stylesheets/icons/email.png +0 -0
  26. data/lib/public/stylesheets/icons/external.png +0 -0
  27. data/lib/public/stylesheets/icons/feed.png +0 -0
  28. data/lib/public/stylesheets/icons/im.png +0 -0
  29. data/lib/public/stylesheets/icons/key.png +0 -0
  30. data/lib/public/stylesheets/icons/pdf.png +0 -0
  31. data/lib/public/stylesheets/icons/tick.png +0 -0
  32. data/lib/public/stylesheets/icons/visited.png +0 -0
  33. data/lib/public/stylesheets/icons/xls.png +0 -0
  34. data/lib/public/stylesheets/ie.css +27 -0
  35. data/lib/public/stylesheets/nosql.css +166 -0
  36. data/lib/public/stylesheets/print.css +30 -0
  37. data/lib/public/stylesheets/screen.css +249 -0
  38. data/lib/public/stylesheets/src/body.png +0 -0
  39. data/lib/public/stylesheets/src/grid.png +0 -0
  40. data/lib/public/stylesheets/src/make_background_images.sh +11 -0
  41. data/lib/public/stylesheets/src/shattered_mirror.png +0 -0
  42. data/lib/public/stylesheets/uv.css +121 -0
  43. data/lib/views/ar.rdiscount +5 -0
  44. data/lib/views/datamapper.rdiscount +43 -0
  45. data/lib/views/layout.rdiscount +38 -0
  46. data/lib/views/main.rdiscount +47 -0
  47. data/lib/views/mongodb.rdiscount +41 -0
  48. data/lib/views/redis.rdiscount +20 -0
  49. data/lib/views/ruby-intro.rdiscount +37 -0
  50. data/lib/views/serializacja-danych.rdiscount +75 -0
  51. data/lib/views/skel.rdiscount +3 -0
  52. data/lib/views/summary.rdiscount +32 -0
  53. metadata +175 -0
@@ -0,0 +1,20 @@
1
+ # Not Only SQL — Data Persistence with Ruby
2
+
3
+ ## TODO list
4
+
5
+ ### Jakieś aplikacje:
6
+
7
+ 1. [pastie](http://www.dzone.com/links/datamapper_sinatra_tutorial.html),
8
+ [pastie2](http://blog.zerosum.org/2008/7/2/clone-pastie-with-sinatra-datamapper-redux).
9
+ 2. [apps written in sinatra, uses datamapper](http://github.com/zapnap/mogo/)
10
+ 3. [A simple Twitter application template, built in Ruby with
11
+ Sinatra and DataMapper](http://github.com/zapnap/retweet/)
12
+
13
+ ### Data persistence
14
+
15
+ 1. [using plain-text files for data persistence](/doc/using-plain-text-files-for-data-persistence.pdf)
16
+ 1. Datamapper adapter for Redis:
17
+ [DataMapper loves Redis](http://whoahbot.com/2009/05/27/redis-and-datamapper.html)
18
+ \([source, example](http://github.com/whoahbot/dm-redis-adapter/)\).
19
+
20
+ 1. redis.spec for Fedora rpm?
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rake'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |s|
8
+ s.name = "nosql-tutorial"
9
+ s.summary = "Notatki do wykladu Utrwalanie Danych"
10
+ s.author = "Wlodek Bzyl"
11
+ s.email = "matwb@univ.gda.pl"
12
+ s.homepage = "http://github.com/wbzyl/nosql"
13
+
14
+ s.description = <<-EOF
15
+ Notatki do wykładu Utrwalanie Danych.
16
+ EOF
17
+
18
+ s.files = %w[Rakefile README.markdown VERSION.yml] + FileList["lib/**/*"]
19
+
20
+ s.add_runtime_dependency 'rack'
21
+ s.add_runtime_dependency 'sinatra'
22
+ s.add_runtime_dependency 'rdiscount'
23
+ s.add_runtime_dependency 'ultraviolet'
24
+ s.add_runtime_dependency 'rack-codehighlighter'
25
+ s.add_runtime_dependency 'sinatra-rdiscount'
26
+ s.add_runtime_dependency 'sinatra-static-assets'
27
+
28
+ s.rubyforge_project = 'nosql'
29
+ end
30
+ Jeweler::GemcutterTasks.new
31
+ rescue LoadError
32
+ puts "Jeweler not available. Install it with:"
33
+ puts " sudo gem install jeweler"
34
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 0
5
+ :build:
@@ -0,0 +1,12 @@
1
+ require 'nosql'
2
+
3
+ gem 'rack-codehighlighter'
4
+ require 'rack/codehighlighter'
5
+
6
+ gem 'ultraviolet'
7
+ require 'uv'
8
+
9
+ use Rack::ShowExceptions
10
+ use Rack::Lint
11
+ use Rack::Codehighlighter, :ultraviolet, :element => '//pre/code', :markdown => true
12
+ run WB::NoSQL.new
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Zobacz przykład: http://gist.github.com/38605
4
+
5
+ require 'rdiscount'
6
+ require 'sinatra/base'
7
+ require 'sinatra/rdiscount'
8
+
9
+ require 'sinatra/url_for'
10
+ require 'sinatra/static_assets'
11
+
12
+ module WB
13
+ class NoSQL < Sinatra::Base
14
+ helpers Sinatra::UrlForHelper
15
+ register Sinatra::StaticAssets
16
+
17
+ # disable overriding public and views dirs
18
+ set :app_file, __FILE__
19
+ set :static, true
20
+
21
+ # the middleware stack can be used internally as well. I'm using it for
22
+ # sessions, logging, and methodoverride. This lets us move stuff out of
23
+ # Sinatra if it's better handled by a middleware component.
24
+ set :logging, true # use Rack::CommonLogger
25
+
26
+ helpers Sinatra::RDiscount
27
+
28
+ # configure blocks:
29
+ # configure :production do
30
+ # end
31
+
32
+ #before do
33
+ # mime :sql, 'text/plain; charset="UTF-8"' # when served by Sinatra itself
34
+ #end
35
+
36
+ # helper methods
37
+
38
+ def page_title
39
+ @title || ""
40
+ end
41
+
42
+ # def title=(name)... does not work, bug?
43
+ def title(name)
44
+ @title = " | #{name}"
45
+ end
46
+
47
+ get '/' do
48
+ rdiscount :main
49
+ end
50
+
51
+ get '/:section' do
52
+ rdiscount :"#{params[:section]}"
53
+ end
54
+
55
+ error do
56
+ e = request.env['sinatra.error']
57
+ Kernel.puts e.backtrace.join("\n")
58
+ 'Application error'
59
+ end
60
+
61
+ # each Sinatra::Base subclass has its own private middleware stack:
62
+ use Rack::Lint
63
+ end
64
+ end
@@ -0,0 +1 @@
1
+ This is a test message: ĄĆĘŁŃÓŚŹŻ ąćęłńóśźż.
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+
5
+ # utwórz wiadomość
6
+
7
+ require 'mail'
8
+ mail = Mail.new do
9
+ from 'wbzyl@inf.ug.edu.pl'
10
+ to 'matwb@ug.edu.pl'
11
+ content_type 'text/plain; charset=UTF-8'
12
+ content_transfer_encoding '8bit'
13
+ mime_version '1.0'
14
+
15
+ subject 'This is a test email: #100'
16
+
17
+ body File.read('body.txt')
18
+ end
19
+
20
+ puts mail.to_s
21
+
22
+ # wyślij ją
23
+
24
+ require 'net/smtp'
25
+
26
+ login = 'wbzyl'
27
+ password = 'alamakota'
28
+
29
+ Net::SMTP.start('inf.ug.edu.pl', 25, 'inf.ug.edu.pl', login, password, :login) do |smtp|
30
+ smtp.send_message mail.to_s, mail.from, mail.to
31
+ end
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'mail'
5
+
6
+ login = 'wbzyl'
7
+ password = 'alamakota'
8
+
9
+ Mail.defaults do
10
+ smtp 'inf.ug.edu.pl', 25 do
11
+ user login
12
+ pass password
13
+ end
14
+ end
15
+
16
+ mail = Mail.deliver do
17
+ from 'wbzyl@inf.ug.edu.pl'
18
+ to 'matwb@ug.edu.pl'
19
+ content_type 'text/plain; charset=UTF-8'
20
+
21
+ subject 'This is a test email: 30'
22
+ body File.read('body.txt')
23
+
24
+ # add_file 'motylek.jpeg'
25
+ # albo tak
26
+ # add_file :filename => 'motylek.jpeg',
27
+ # :data => File.read('motylek.jpeg'),
28
+ # :content_transfer_encoding => 'base64'
29
+ end
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'mail'
5
+
6
+ login = 'matwb'
7
+ password = 'alamakota'
8
+
9
+ Mail.defaults do
10
+ pop3 'julia.univ.gda.pl', 110 do
11
+ user login
12
+ pass password
13
+ end
14
+ end
15
+
16
+ emails = Mail.first(:count => 4, :order => :asc) do |email|
17
+ puts email.date.to_s
18
+ puts email.from
19
+ puts email.subject.to_s
20
+ # puts email.body.to_s[0..40]
21
+ # puts email.message_id
22
+ # puts email.to
23
+ # puts email.cc
24
+ end
@@ -0,0 +1,11 @@
1
+ ---
2
+ - !ruby/object:Contact
3
+ email: joe@somewhere.abc
4
+ extras:
5
+ :instrument: Cello
6
+ home:
7
+ :street1: 123 Main Street
8
+ :city: Somewhere
9
+ name: Joe Smith
10
+ work:
11
+ :phone: (000) 123-4567
@@ -0,0 +1,105 @@
1
+ require 'gdbm'
2
+ require 'fileutils'
3
+
4
+ class ContactList
5
+
6
+ attr_reader :contact_cache
7
+
8
+ def initialize(dir)
9
+ @dir = dir
10
+ @contact_cache = []
11
+ end
12
+
13
+ def [](name)
14
+ contact = @contact_cache.find {|c| c.name == name }
15
+ return contact if contact
16
+ contact = Contact.new(name)
17
+ Dir.chdir(@dir) do
18
+ if File.directory?(contact.dirname)
19
+ populate_contact(contact)
20
+ @contact_cache << contact
21
+ else
22
+ contact = nil
23
+ end
24
+ end
25
+ contact
26
+ end
27
+
28
+ def populate_contact(contact)
29
+ Dir.chdir(contact.dirname) do
30
+ contact.open
31
+ end
32
+ end
33
+
34
+ def <<(contact)
35
+ Dir.chdir(@dir) do
36
+ Dir.mkdir(contact.dirname) unless File.exists?(contact.dirname)
37
+ populate_contact(contact)
38
+ end
39
+ @contact_cache << contact
40
+ end
41
+
42
+ def delete(name)
43
+ contact = self[name]
44
+ return false unless contact
45
+ contact.close
46
+ Dir.chdir(@dir) do
47
+ FileUtils.rm_rf(contact.dirname)
48
+ end
49
+ contact_cache.delete_if {|c| c.name == name }
50
+ true
51
+ end
52
+
53
+ def directory_names
54
+ Dir["#{@dir}/*"]
55
+ end
56
+
57
+ def size
58
+ directory_names.size
59
+ end
60
+
61
+ def empty?
62
+ directory_names.empty?
63
+ end
64
+
65
+ end
66
+
67
+
68
+ class Contact
69
+
70
+ COMPONENTS = ["home", "extras", "work"]
71
+
72
+ attr_accessor :name, *COMPONENTS
73
+
74
+ attr_reader :dirname
75
+
76
+ def initialize(name)
77
+ @name = name
78
+ @dirname = @name.gsub(" ", "_")
79
+ end
80
+
81
+ def components
82
+ COMPONENTS.map {|comp_name| self.send(comp_name) }
83
+ end
84
+
85
+ def open
86
+ COMPONENTS.each do |component|
87
+ self.send(component + "=", GDBM.new(component))
88
+ end
89
+ end
90
+
91
+ def close
92
+ components.each do |component|
93
+ component.close unless component.closed?
94
+ end
95
+ end
96
+
97
+ def email
98
+ extras["email"]
99
+ end
100
+
101
+ def email=(e)
102
+ extras["email"] = e
103
+ end
104
+
105
+ end
@@ -0,0 +1,51 @@
1
+ require 'test/unit'
2
+ require 'contacts_g'
3
+
4
+ Dir.mkdir("gdbm_contacts") unless File.exist?("gdbm_contacts")
5
+
6
+ class GDBMTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @list = ContactList.new("gdbm_contacts")
10
+ @contact = Contact.new("Joe Smith")
11
+
12
+ @list << @contact
13
+
14
+ @contact.home["street1"] = "123 Main Street"
15
+ @contact.home["city"] = "Somewhere"
16
+ @contact.work["phone"] = "(000) 123-4567"
17
+ @contact.extras["instrument"] = "Cello"
18
+ @contact.email = "joe@somewhere.abc"
19
+ end
20
+
21
+ def teardown
22
+ @list.delete("Joe Smith") if @list["Joe Smith"]
23
+ end
24
+
25
+ def test_retrieving_a_contact_from_list
26
+ contact = @list["Joe Smith"]
27
+ assert_equal("Joe Smith", contact.name)
28
+ end
29
+
30
+ def test_delete_a_contact_from_list
31
+ assert(!@list.empty?)
32
+ @list.delete("Joe Smith")
33
+ assert(@list.empty?)
34
+ assert(@list.contact_cache.empty?)
35
+ end
36
+
37
+ def test_home
38
+ contact = @list["Joe Smith"]
39
+ assert_equal("123 Main Street", contact.home["street1"])
40
+ end
41
+
42
+ def test_email
43
+ contact = @list["Joe Smith"]
44
+ assert_equal("joe@somewhere.abc", contact.email)
45
+ end
46
+
47
+ def test_non_existent_contact_is_nil
48
+ assert_equal(nil, @list["Some Person"])
49
+ end
50
+
51
+ end
@@ -0,0 +1,57 @@
1
+ require "yaml"
2
+
3
+ class ContactList
4
+ attr_accessor :contacts
5
+
6
+ def initialize(file)
7
+ @file = file
8
+ @contacts = []
9
+ end
10
+
11
+ def <<(contact)
12
+ @contacts << contact
13
+ end
14
+
15
+ def delete(name)
16
+ @contacts.delete_if {|c| c.name == name }
17
+ end
18
+
19
+ def empty?
20
+ @contacts.empty?
21
+ end
22
+
23
+ def size
24
+ @contacts.size
25
+ end
26
+
27
+ def [](name)
28
+ @contacts.find {|c| c.name == name }
29
+ end
30
+
31
+ def save
32
+ File.open(@file, "w") do |fh|
33
+ fh.puts(@contacts.to_yaml)
34
+ end
35
+ end
36
+
37
+ def self.load(file)
38
+ list = new(file)
39
+ list.contacts = YAML.load(File.read(file))
40
+ list
41
+ end
42
+
43
+ end
44
+
45
+
46
+ class Contact
47
+ attr_reader :name, :email, :home, :work, :extras
48
+ attr_writer :name, :email
49
+
50
+ def initialize(name)
51
+ @name = name
52
+ @home = {}
53
+ @work = {}
54
+ @extras = {}
55
+ end
56
+
57
+ end