nosql-tutorial 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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