squixtures 0.0.2

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.
@@ -0,0 +1,17 @@
1
+ #! /usr/bin/env ruby
2
+ # Copyright (c), 2012 Peter Wood
3
+
4
+ module Squixtures
5
+ # This module is intended for inclusion into other classes to enable them
6
+ # with fixture functionality.
7
+ module Fixtures
8
+ # This method is really just a wrapper around the Suxtures::fixtures
9
+ # method.
10
+ #
11
+ # === Parameters
12
+ # names:: The name of the fixtures to be loaded.
13
+ def fixtures(*names)
14
+ Squixtures.fixtures(*names)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ #! /usr/bin/env ruby
2
+ # Copyright (c), 2012 Peter Wood
3
+
4
+ module Squixtures
5
+ module HelperFactory
6
+ # This method fetches an appropriate database helper instance based on the
7
+ # database connection details provided. The method will raise an exception
8
+ # if an unrecognised database type is encountered.
9
+ #
10
+ # ==== Parameters
11
+ # settings:: A Hash of the database connection settings.
12
+ def self.create_helper(settings)
13
+ adapter = settings['adapter']
14
+ helper = nil
15
+ case adapter
16
+ when 'postgresql'
17
+ helper = PostgresHelper.new
18
+
19
+ when 'sqlite3'
20
+ helper = SQLite3Helper.new
21
+ end
22
+
23
+ if helper.nil?
24
+ raise SquixturesError.new("Unrecognised database adapter '#{adapter}' encountered.")
25
+ end
26
+ helper
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,74 @@
1
+ #! /usr/bin/env ruby
2
+ # Copyright (c), 2012 Peter Wood
3
+
4
+ require 'stringio'
5
+
6
+ module Squixtures
7
+ # This class encapsulates the functionality to load multiple fixtures.
8
+ class Loader
9
+ # Add logging to the class.
10
+ LogJam.apply(self, "squixtures")
11
+
12
+ # Constructor the Loader class.
13
+ #
14
+ # ==== Parameters
15
+ # configuration:: The configuration to be used by the loader to load
16
+ # fixtures.
17
+ def initialize(configuration)
18
+ @configuration = configuration
19
+ end
20
+
21
+ # This method performs the actual work of loading the fixture data
22
+ # specified.
23
+ #
24
+ # ==== Parameters
25
+ # *names:: A collection of the fixture names to be loaded.
26
+ def load(*names)
27
+ # Generate the list of fixtures to be loaded.
28
+ fixtures = []
29
+
30
+ # Expand :all to a list of fixture names.
31
+ if names.size == 1 && names[0] == :all
32
+ names = []
33
+ fixtures_path = Squixtures.find_fixtures_dir
34
+ if !fixtures_path.nil?
35
+ Dir.glob("#{fixtures_path}/*.yml").each do |file_path|
36
+ file_name = File.basename(file_path)
37
+ extension = File.extname(file_name)
38
+ names << file_name[0, file_name.length - extension.length].intern
39
+ end
40
+ end
41
+ end
42
+
43
+ names.each do |name|
44
+ fixtures << Fixture.new(name, @configuration)
45
+ end
46
+
47
+ # Connect to the database.
48
+ url = Squixtures.get_connection_url(@configuration[:database])
49
+ Loader.log.debug "Database Connection URL: #{url}"
50
+ connection = Sequel.connect(url)
51
+
52
+ # Create the database helper class.
53
+ helper = HelperFactory.create_helper(@configuration[:database])
54
+
55
+ # Perform the actual load.
56
+ begin
57
+ Loader.log.debug "Calling before_load as precursor to fixture load."
58
+ helper.before_load(fixtures, connection)
59
+
60
+ Loader.log.debug "Starting fixtures load."
61
+ fixtures.each do |fixture|
62
+ if @configuration[:transactional]
63
+ connection.transaction {fixture.load(connection)}
64
+ else
65
+ fixture.load(connection)
66
+ end
67
+ end
68
+
69
+ Loader.log.debug "Calling after_load after fixtures have been loaded."
70
+ helper.after_load(fixtures, connection)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,77 @@
1
+ #! /usr/bin/env ruby
2
+ # Copyright (c), 2012 Peter Wood
3
+
4
+ require 'stringio'
5
+
6
+ module Squixtures
7
+ # A class to contain elements specific to the Postgres system.
8
+ class PostgresHelper
9
+ # Add logging to the class.
10
+ LogJam.apply(self, "squixtures")
11
+
12
+ # This method is invoked immediately before a fixture load starts and
13
+ # performs all work necessary to facilitate the load.
14
+ #
15
+ # ==== Parameters
16
+ # fixtures:: A collection of the fixture objects to be loaded.
17
+ # connection:: The database connection that the load will be performed
18
+ # through.
19
+ def before_load(fixtures, connection)
20
+ PostgresHelper.log.debug "PostgresHelper.before_load called."
21
+ fixtures.each do |fixture|
22
+ begin
23
+ connection.run("alter table #{fixture.table_name} disable trigger all")
24
+ rescue
25
+ connection.run("alter table #{fixture.table_name} disable trigger user")
26
+ end
27
+ end
28
+ end
29
+
30
+ # This method is invoked immediately after a fixture load completes and
31
+ # performs all clean up necessary.
32
+ #
33
+ # ==== Parameters
34
+ # fixtures:: A collection of the fixture objects to be loaded.
35
+ # connection:: The database connection that the load will be performed
36
+ # through.
37
+ def after_load(fixtures, connection)
38
+ PostgresHelper.log.debug "PostgresHelper.after_load called."
39
+ fixtures.each do |fixture|
40
+ begin
41
+ connection.run("alter table #{fixture.table_name} enable trigger all")
42
+ rescue
43
+ connection.run("alter table #{fixture.table_name} enable trigger user")
44
+ end
45
+ end
46
+ end
47
+
48
+ # This method is an instance level version of the get_connection_url
49
+ # method declared at the class level.
50
+ def get_connection_url(settings)
51
+ PostgresHelper.get_connection_url(settings)
52
+ end
53
+
54
+ # This method converts a typical set of database connection settings, such
55
+ # as those in a Rails database.yml file, into the URL to be used to connect
56
+ # to a Postgres database using the Sequel library.
57
+ #
58
+ # ==== Parameters
59
+ # settings:: A Hash of the settings that will be used to generate the
60
+ # connection URL.
61
+ def self.get_connection_url(settings)
62
+ url = StringIO.new
63
+ url << "postgres://"
64
+ if settings.include?("username")
65
+ url << settings["username"]
66
+ url << ":#{settings['password']}" if settings.include?("password")
67
+ end
68
+ url << "@"
69
+ if settings.include?("host")
70
+ url << "#{settings['host']}"
71
+ url << ":#{settings['port']}" if settings.include?("port")
72
+ end
73
+ url << "/#{settings['database']}" if settings.include?("database")
74
+ url.string
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,51 @@
1
+ #! /usr/bin/env ruby
2
+ # Copyright (c), 2012 Peter Wood
3
+
4
+ module Squixtures
5
+ # A class to contain elements specific to the SQLite3 system.
6
+ class SQLite3Helper
7
+ # Add logging to the class.
8
+ LogJam.apply(self, "squixtures")
9
+
10
+ # This method is invoked immediately before a fixture load starts and
11
+ # performs all work necessary to facilitate the load.
12
+ #
13
+ # ==== Parameters
14
+ # fixtures:: A collection of the fixture objects to be loaded.
15
+ # connection:: The database connection that the load will be performed
16
+ # through.
17
+ def before_load(fixtures, connection)
18
+ SQLite3Helper.log.debug "SQLite3Helper.before_load called."
19
+ connection.run("PRAGMA foreign_keys = OFF")
20
+ end
21
+
22
+ # This method is invoked immediately after a fixture load completes and
23
+ # performs all clean up necessary.
24
+ #
25
+ # ==== Parameters
26
+ # fixtures:: A collection of the fixture objects to be loaded.
27
+ # connection:: The database connection that the load will be performed
28
+ # through.
29
+ def after_load(fixtures, connection)
30
+ SQLite3Helper.log.debug "SQLite3Helper.after_load called."
31
+ connection.run("PRAGMA foreign_keys = ON")
32
+ end
33
+
34
+ # This method is an instance level version of the get_connection_url
35
+ # method declared at the class level.
36
+ def get_connection_url(settings)
37
+ SQLite3Helper.get_connection_url(settings)
38
+ end
39
+
40
+ # This method converts a typical set of database connection settings, such
41
+ # as those in a Rails database.yml file, into the URL to be used to connect
42
+ # to a Postgres database using the Sequel library.
43
+ #
44
+ # ==== Parameters
45
+ # settings:: A Hash of the settings that will be used to generate the
46
+ # connection URL.
47
+ def self.get_connection_url(settings)
48
+ "sqlite://#{settings['database']}"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,6 @@
1
+ #! /usr/bin/env ruby
2
+ # Copyright (c), 2012 Peter Wood
3
+
4
+ module Squixtures
5
+ VERSION = "0.0.2"
6
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/squixtures/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Peter Wood"]
6
+ gem.email = ["ruby@blacknorth.com"]
7
+ gem.description = %q{Squixtures is a library that provides a data fixtures facility ala the fixtures typically used in unit tests. The library makes use of the Sequel library to provide a degree of database independence (needs more work) and use the LogJam library to unify logging output.}
8
+ gem.summary = %q{Simple fixtures functionality.}
9
+ gem.homepage = ""
10
+
11
+ gem.add_dependency('sequel', '>= 3.36.1')
12
+ gem.add_dependency('logjam', '>= 0.0.3')
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.name = "squixtures"
18
+ gem.require_paths = ["lib"]
19
+ gem.version = Squixtures::VERSION
20
+ end
@@ -0,0 +1,41 @@
1
+ # Squixtures Test
2
+ This directory contains files used in testing the Squixtures library. The
3
+ process of preparing for and running these tests is outlined below.
4
+
5
+ ## Preparing The Test Database
6
+ The test files expect that a test database will have been created before they
7
+ are run. To assist in this process the details needed to create the test
8
+ database have been encapsulated into a set of Sequel migrations that are stored
9
+ in the db/migrations sudirectory of the test folder. To create the database for
10
+ testing the library with SQLite3 you would use a command such as the following
11
+ to create the test database...
12
+
13
+ $> sequel -m db/migrations sqlite://db/squixtures.db
14
+
15
+ The command given above assumes that it is being executed from the test folder
16
+ with the main project folder. This will create a new database file in a file
17
+ called squixtures.db in the db subdirectory. To create the test database for
18
+ Postgres is a little more convoluted but would following a series of commands
19
+ such as the following...
20
+
21
+ $> createdb -E UTF-8 -U postgres squixtures
22
+ $> sequel -m db/migrations postgres://postgres:password@localhost:5432/squixtures
23
+
24
+ The second command assumes that the password for the postgres user is password,
25
+ alter this as necessary. To roll a migration back completely you can use a
26
+ command such as...
27
+
28
+ $> sequel -m db/migrations postgres://postgres:password@localhost:5432/squixtures -M 0
29
+
30
+ ## Executing A Test
31
+ All of the tests are stored as Ruby source files within the test subdirectory
32
+ of the main project folder. To execute any of the tests you would use a command
33
+ such as the following...
34
+
35
+ $> ruby -I../lib squixtures_include_tests.rb
36
+
37
+ Again, it is assumed this command is executed from within the test folder. The
38
+ command specifies an include path to the squixtures lib folder which allows for
39
+ execution of the tests without the library actually being installed. If you have
40
+ the library installed and simply want to execute the tests then drop the '-I'
41
+ parameter from the command.
@@ -0,0 +1,17 @@
1
+ # SQLite3 configuration.
2
+ # test:
3
+ # adapter: sqlite3
4
+ # database: db/squixtures.db
5
+ # pool: 5
6
+ # timeout: 5000
7
+
8
+ # Postgres configuration.
9
+ test:
10
+ adapter: postgresql
11
+ database: squixtures
12
+ username: postgres
13
+ password:
14
+ port: 5432
15
+ host: localhost
16
+ pool: 5
17
+ timeout: 5000
@@ -0,0 +1,16 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table(:users) do
4
+ primary_key :id
5
+ String :email, :null => false, :size => 255, :unique => true
6
+ String :passwd, :null => false, :size => 100
7
+ Integer :status, :null => false
8
+ Time :created, :null => false
9
+ Time :updated, :null => true
10
+ end
11
+ end
12
+
13
+ down do
14
+ drop_table(:users)
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table(:orders) do
4
+ primary_key :id
5
+ foreign_key :user_id, :users
6
+ Integer :status, :null => false
7
+ Time :created, :null => false
8
+ Time :updated, :null => true
9
+ end
10
+ end
11
+
12
+ down do
13
+ drop_table(:orders)
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table(:categories) do
4
+ primary_key :id
5
+ String :name, :limit => 100, :null => false
6
+ Time :created, :null => false
7
+ Time :updated, :null => true
8
+ end
9
+ end
10
+
11
+ down do
12
+ drop_table(:categories)
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table(:products) do
4
+ primary_key :id
5
+ foreign_key :category_id, :categories
6
+ String :name, :size => 200
7
+ Float :cost, :null => false, :precision => 6, :scale => 2
8
+ Time :created, :null => false
9
+ Time :updated, :null => true
10
+ end
11
+ end
12
+
13
+ down do
14
+ drop_table(:products)
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table(:order_products) do
4
+ primary_key :id
5
+ foreign_key :order_id, :orders
6
+ foreign_key :product_id, :products
7
+ Integer :quantity, :null => false
8
+ Time :created, :null => false
9
+ Time :updated, :null => true
10
+ end
11
+ end
12
+
13
+ down do
14
+ drop_table(:order_products)
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ one:
2
+ id: 1
3
+ name: Jackets
4
+ created: <%= Time.now %>
5
+
6
+ two:
7
+ id: 1
8
+ name: Footwear
9
+ created: <%= Time.now - 5400 %>
10
+ updated: <%= Time.now %>
@@ -0,0 +1,12 @@
1
+ ten:
2
+ id: 10
3
+ email: a.dent@end-of-universe.com
4
+ passwd: password
5
+ status: 1
6
+ created: <%= Time.now %>
7
+ eleven:
8
+ id: 11
9
+ email: f.prefect@end-of-universe.com
10
+ passwd: password
11
+ status: 1
12
+ created: <%= Time.now %>