Skip to content
This repository has been archived by the owner on May 13, 2019. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewd committed Mar 5, 2009
0 parents commit 06f62f5
Show file tree
Hide file tree
Showing 15 changed files with 538 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pkg
4 changes: 4 additions & 0 deletions History.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
== 0.0.1 2009-03-02

* 1 major enhancement:
* Initial release
14 changes: 14 additions & 0 deletions Manifest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
History.txt
Manifest.txt
README.rdoc
Rakefile
lib/sqlstate.rb
lib/sqlstate/core.rb
lib/sqlstate/modules.rb
lib/sqlstate/postgres.rb
lib/sqlstate/standard.rb
script/console
script/destroy
script/generate
test/test_helper.rb
test/test_sqlstate.rb
69 changes: 69 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
= sqlstate

* http://github.com/matthewd/sqlstate

== DESCRIPTION:

An exception hierarchy corresponding to SQLSTATE codes from the SQL
Standard.

Most SQL platforms can return their error codes in the form of an
SQLSTATE; this library ensures differing database drivers can all throw
the same errors.

A common library reduces the temptation, when writing a database driver,
to simply throw all possible errors using a single generic exception.


The primary intended audience is authors of database drivers; other
users only interaction with this library should be in catching its
exceptions.

== FEATURES:

* Exception hierarchy that maps to a good portion of the Standard's
SQLSTATE codes
* Ability to extend the hierarchy for a database platform, mixing vendor
codes with Standard ones
* Vendor-specific exception hierarchies for:
* PostgreSQL

== SYNOPSIS:

require 'sqlstate'
raise SqlState.create('22012') # Division By Zero


require 'sqlstate/postgres'
ex = SqlState::PostgresError.create('08P01') # Protocol Violation
ex.hint = 'Try doing the right thing.'
raise ex

== INSTALL:

sudo gem install sqlstate

== LICENSE:

(The MIT License)

Copyright (c) 2009 Matthew Draper

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 changes: 22 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
require File.dirname(__FILE__) + '/lib/sqlstate'

# Generate all the Rake tasks
# Run 'rake -T' to see list of generated tasks (from gem root directory)
$hoe = Hoe.new('sqlstate', SqlState::VERSION) do |p|
p.developer('Matthew Draper', 'matthew@trebex.net')
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
p.rubyforge_name = 'sqlstate'
p.extra_dev_deps = [
['newgem', ">= #{::Newgem::VERSION}"]
]

p.clean_globs |= %w[**/.DS_Store tmp *.log]
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
p.rsync_args = '-av --delete --ignore-errors'
end

require 'newgem/tasks' # load /tasks/*.rake
Dir['tasks/**/*.rake'].each { |t| load t }

9 changes: 9 additions & 0 deletions lib/sqlstate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
$:.unshift(File.dirname(__FILE__)) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))

class SqlState < StandardError
VERSION = '0.0.1'
end

require 'sqlstate/standard'

16 changes: 16 additions & 0 deletions lib/sqlstate/core.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

require 'sqlstate/modules'

class SqlState < StandardError
extend SqlStateRoot

SQL_STATE = 'HY000'
MESSAGE = 'Unrecognised SQL Error'

attr_reader :sql_state
def initialize(sql_state=self.class::SQL_STATE, message=self.class::MESSAGE)
@sql_state = sql_state
super(message)
end
end

66 changes: 66 additions & 0 deletions lib/sqlstate/modules.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

module SqlState::SqlStateClass
attr_reader :sqlstate_subclasses
attr_writer :sqlstate_prefix
def self.extended(target)
target.instance_variable_set :@sqlstate_subclasses, {}
end
def define(suffix, description, parent=nil)
parent ||= self
sql_state = (@sqlstate_prefix || '') + suffix
name = description.gsub(/([A-Za-z])([A-Za-z0-9]+)/) { $1.upcase + $2.downcase }.gsub(/[^A-Za-z0-9]+/, '')
klass = Class.new(parent)
klass.const_set :SQL_STATE, sql_state
klass.const_set :MESSAGE, description
klass.instance_variable_set :@root, @root || self
(@root || self).const_set name, klass
sqlstate_subclasses[sql_state] = klass
end
def subclass_for(sql_state)
sqlstate_subclasses[sql_state]
end
end

module SqlState::SqlStateRoot
include SqlState::SqlStateClass

def self.extended(target)
target.instance_variable_set :@sqlstate_subclasses, {}
end

def set_parent_root(v)
@parent_root = v
end
def parent_root
@parent_root || (self == SqlState ? nil : SqlState)
end

def class_for(state)
sqlstate_subclasses[state[0, 2] + '000']
end
def for(sql_state)
subclass = subclass_for(sql_state)
subclass ||= class_for(sql_state).subclass_for(sql_state) if class_for(sql_state)
subclass ||= parent_root.for(sql_state) if parent_root
subclass || self
end

def create(sql_state, *args)
self.for(sql_state).new(sql_state, *args)
end

def define_class(prefix, description)
klass = define("#{prefix}000", description)
klass.send :extend, SqlState::SqlStateClass
klass.sqlstate_prefix = prefix
yield klass if block_given?
klass
end

def define(sql_state, description)
parent = class_for(sql_state)
parent ||= parent_root && parent_root.class_for(sql_state)
super(sql_state, description, parent)
end
end

106 changes: 106 additions & 0 deletions lib/sqlstate/postgres.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

require 'sqlstate/standard'

class SqlState::PostgresError < SqlState
extend SqlStateRoot

module Details
attr_accessor :details, :hint, :context
attr_accessor :source_file, :source_line, :source_function
end

def create(sql_state, message=nil)
obj = super
obj.send(:extend, Details)
obj
end


define_class 'P0', 'PL/pgSQL Error' do |k|
k.define '001', 'RAISE EXCEPTION'
k.define '002', 'No Data Found'
k.define '003', 'Too Many Rows'
end

define_class 'XX', 'Internal Error' do |k|
k.define '001', 'Data Corrupted'
k.define '002', 'Index Corrupted'
end

define '08P01', 'Protocol Violation'

define '0LP01', 'Invalid Grant Operation'

define '22P06', 'Nonstandard Use Of Escape Character'
define '22P01', 'Floating Point Exception'
define '22P02', 'Invalid Text Representation'
define '22P03', 'Invalid Binary Representation'
define '22P04', 'Bad Copy File Format'
define '22P05', 'Untranslatable Character'

define '23502', 'Not Null Violation'
define '23503', 'Foreign Key Violation'
define '23505', 'Unique Violation'
define '23514', 'Check Violation'

define '25P01', 'No Active SQL Transaction'
define '25P02', 'In Failed SQL Transaction'

define '2BP01', 'Dependent Objects Still Exist'

define '39P01', 'Trigger Protocol Violated'
define '39P02', 'SRF Protocol Violated'

define '40P01', 'Deadlock Detected'

define '42601', 'Syntax Error'
define '42501', 'Insufficient Privilege'
define '42846', 'Cannot Coerce'
define '42803', 'Grouping Error'
define '42P19', 'Invalid Recursion'
define '42830', 'Invalid Foreign Key'
define '42602', 'Invalid Name'
define '42622', 'Name Too Long'
define '42939', 'Reserved Name'
define '42804', 'Datatype Mismatch'
define '42P18', 'Indeterminate Datatype'
define '42809', 'Wrong Object Type'
define '42703', 'Undefined Column'
define '42883', 'Undefined Function'
define '42P01', 'Undefined Table'
define '42P02', 'Undefined Parameter'
define '42704', 'Undefined Object'
define '42701', 'Duplicate Column'
define '42P03', 'Duplicate Cursor'
define '42P04', 'Duplicate Database'
define '42723', 'Duplicate Function'
define '42P05', 'Duplicate Prepared Statement'
define '42P06', 'Duplicate Schema'
define '42P07', 'Duplicate Table'
define '42712', 'Duplicate Alias'
define '42710', 'Duplicate Object'
define '42702', 'Ambiguous Column'
define '42725', 'Ambiguous Function'
define '42P08', 'Ambiguous Parameter'
define '42P09', 'Ambiguous Alias'
define '42P10', 'Invalid Column Reference'
define '42611', 'Invalid Column Definition'
define '42P11', 'Invalid Cursor Definition'
define '42P12', 'Invalid Database Definition'
define '42P13', 'Invalid Function Definition'
define '42P14', 'Invalid Prepared Statement Definition'
define '42P15', 'Invalid Schema Definition'
define '42P16', 'Invalid Table Definition'
define '42P17', 'Invalid Object Definition'

define '55P02', 'Cant Change Runtime Param'
define '55P03', 'Lock Not Available'

define '57P01', 'Admin Shutdown'
define '57P02', 'Crash Shutdown'
define '57P03', 'Cannot Connect Now'

define '58P01', 'Undefined File'
define '58P02', 'Duplicate File'
end

Loading

0 comments on commit 06f62f5

Please sign in to comment.