-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#73 Convert CID to SQL statements #96
Changes from 5 commits
567cbdd
eef7afd
a8374be
934c93b
9712b1f
983e4af
7817416
8a8bb94
739854e
df72e8e
35644b2
84649d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -243,6 +243,7 @@ def __init__(self, description, default=None): | |
raise errors.InterfaceError( | ||
'value for %s must a number, a single character or a symbolic name but is: %s' | ||
% (name_for_code, _compat.text_repr(next_value)), location) | ||
|
||
if ellipsis_found: | ||
if upper is None: | ||
upper = value_as_int | ||
|
@@ -281,7 +282,7 @@ def __init__(self, description, default=None): | |
# Handle "...". | ||
raise errors.InterfaceError( | ||
'ellipsis (...) must be preceded and/or succeeded by number', location) | ||
else: | ||
else: # maybe useless?! | ||
# Handle "". | ||
result = None | ||
else: | ||
|
@@ -427,7 +428,7 @@ def _item_contains(self, item, value): | |
lower = item[0] | ||
upper = item[1] | ||
if lower is None: | ||
if upper is None: | ||
if upper is None: # ?? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cleaned this up with #97, just merge. |
||
# Handle "" | ||
result = True | ||
else: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
from __future__ import unicode_literals | ||
|
||
import os.path | ||
import six | ||
import sqlite3 | ||
|
||
from cutplace import _tools | ||
|
@@ -177,7 +178,7 @@ def as_sql_create_table(cid, dialect='ansi'): | |
constraints = "" | ||
|
||
# get column definitions and constraints for all fields | ||
for field in cid._field_formats: | ||
for field in cid.field_formats: | ||
column_def, constraint = field.as_sql(dialect) | ||
result += column_def + ",\n" | ||
|
||
|
@@ -207,3 +208,27 @@ def as_sql_create_table(cid, dialect='ansi'): | |
cursor.close() | ||
|
||
return result | ||
|
||
|
||
def as_sql_create_inserts(cid, source_data_reader): | ||
""" | ||
:param Cid cid: | ||
:param validio.Reader source_data_reader: | ||
:return: | ||
""" | ||
assert cid | ||
assert source_data_reader | ||
|
||
file_name = os.path.basename(cid._cid_path) | ||
table_name = file_name.split('.')[0] | ||
|
||
for row in source_data_reader.rows(): | ||
for i in range(len(row)): | ||
|
||
# HACK: can't use isinstance() function because of circular dependency when importing fields module | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we still have a circular dependency? |
||
fiel_type = six.text_type((cid.field_formats[i]).__class__.__name__) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: |
||
if fiel_type not in ('IntegerFieldFormat', 'DecimalFieldFormat'): | ||
row[i] = "'" + row[i] + "'" | ||
|
||
result = "insert into %s(%s) values (%s);" % (table_name, ', '.join(cid.field_names), ', '.join(row)) | ||
yield result |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,6 +90,14 @@ def test_fails_on_invalid_character(self): | |
"character 'x' (code point U+0078, decimal 120) in field 'something' at column 3 must be an allowed" | ||
" character: 97...99", six.text_type(anticipated_error)) | ||
|
||
def test_can_raise_not_implemented_error(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to test for |
||
field_format = fields.AbstractFieldFormat('x', False, '3...5', '', _ANY_FORMAT) | ||
self.assertRaises(NotImplementedError, field_format.validated_value, 4) | ||
|
||
def test_can_output_field_format_as_string(self): | ||
field_format = fields.AbstractFieldFormat('x', False, '3...5', '', _ANY_FORMAT) | ||
self.assertEqual(six.text_type(field_format), "AbstractFieldFormat('x', False, Range('3...5'), '')") | ||
|
||
|
||
class DateTimeFieldFormatTest(unittest.TestCase): | ||
""" | ||
|
@@ -475,6 +483,14 @@ def test_fails_on_value_not_matching_pattern(self): | |
self.assertRaises(errors.FieldValueError, field_format.validated, "hang") | ||
|
||
|
||
class PublicFieldFunctionTest(unittest.TestCase): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Migrate this test to the |
||
""" | ||
Test for public functions in the fields module | ||
""" | ||
def test_fails_on_non_ascii_character(self): | ||
self.assertRaises(errors.InterfaceError, fields.validated_field_name, "a�") | ||
|
||
|
||
if __name__ == '__main__': # pragma: no cover | ||
logging.basicConfig() | ||
logging.getLogger("cutplace").setLevel(logging.INFO) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -149,6 +149,9 @@ def test_fails_on_string_with_multiple_characters(self): | |
def test_fails_on_unterminated_string(self): | ||
self.assertRaises(errors.InterfaceError, ranges.Range, "\"\"") | ||
|
||
def test_fails_on_missing_numbers(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to |
||
self.assertRaises(errors.InterfaceError, ranges.Range, "...") | ||
|
||
def test_can_validate_with_lower_and_upper_limit(self): | ||
lower_and_upper_range = ranges.Range("-1...1") | ||
lower_and_upper_range.validate("x", - 1) | ||
|
@@ -202,12 +205,25 @@ def test_can_create_range_from_length(self): | |
ranges.create_range_from_length( | ||
ranges.Range("3...4, 10...")).items, [(-999, -10), (100, 9999), (None, -100000000), (1000000000, None)]) | ||
|
||
def test_can_display_lower_is_upper_length(self): | ||
self.assertEqual(six.text_type(ranges.Range("9...9")), "9") | ||
|
||
def test_can_display_multi_range(self): | ||
self.assertEqual(six.text_type(ranges.Range("9...10, 11...13")), "9...10, 11...13") | ||
|
||
def test_fails_on_create_range_from_negative_length(self): | ||
self.assertRaises(errors.RangeValueError, ranges.create_range_from_length, ranges.Range("-19...-1")) | ||
self.assertRaises(errors.RangeValueError, ranges.create_range_from_length, ranges.Range("-19...1")) | ||
self.assertRaises(errors.RangeValueError, ranges.create_range_from_length, ranges.Range("-1...0")) | ||
self.assertRaises(errors.RangeValueError, ranges.create_range_from_length, ranges.Range("0...0")) | ||
|
||
def test_can_represent_range_containing_none(self): | ||
none_range = ranges.Range(None) | ||
self.assertEqual(six.text_type(none_range), six.text_type(None)) | ||
upper_none_range = ranges.Range("1...") | ||
upper_none_range.items.append(None) | ||
self.assertEqual(six.text_type(upper_none_range), "1..., None") | ||
|
||
|
||
class DecimalRangeTest(unittest.TestCase): | ||
|
||
|
@@ -408,6 +424,22 @@ def test_can_handle_scientific_notation(self): | |
self.assertEqual(7, decimal_range.scale) | ||
self.assertEqual(2, decimal_range.precision) | ||
|
||
def test_can_display_lower_is_upper_length(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to |
||
self.assertEqual(six.text_type(ranges.DecimalRange("9.9...9.9")), "9.9...9.9") | ||
|
||
def test_can_display_multi_range(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to |
||
self.assertEqual(six.text_type(ranges.DecimalRange("9.1...10.9, 11...13")), "9.1...10.9, 11.0...13.0") | ||
|
||
def test_can_represent_range_containing_none(self): | ||
none_range = ranges.DecimalRange(None) | ||
self.assertEqual(six.text_type(none_range), six.text_type(None)) | ||
upper_none_range = ranges.DecimalRange("1...") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which parts of the code is this test supposed to cover that are not already covered by the other tests? Adding items after the constructor should not be supported by |
||
upper_none_range.items.append(None) | ||
self.assertEqual(six.text_type(upper_none_range), "1, None") | ||
|
||
def test_fails_on_non_decimal_value_to_validate(self): | ||
decimal_range = ranges.DecimalRange("1.1...2.2") | ||
self.assertRaises(errors.RangeValueError, decimal_range.validate, "x", "a") | ||
|
||
if __name__ == "__main__": # pragma: no cover | ||
unittest.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace whole
else
clause withassert False
.