Skip to content
This repository was archived by the owner on Mar 20, 2026. It is now read-only.

Commit 57ef91e

Browse files
author
Ilya Gurov
authored
refactor: rename Column class into ColumnInfo, refactor it and cover with unit tests (#520)
1 parent f68f426 commit 57ef91e

2 files changed

Lines changed: 90 additions & 38 deletions

File tree

google/cloud/spanner_dbapi/cursor.py

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def description(self):
219219
columns = []
220220
for field in row_type.fields:
221221
columns.append(
222-
Column(
222+
ColumnInfo(
223223
name=field.name,
224224
type_code=field.type.code,
225225
# Size of the SQL type of the column.
@@ -352,7 +352,9 @@ def get_table_column_schema(self, table_name):
352352
return self._connection.get_table_column_schema(table_name)
353353

354354

355-
class Column:
355+
class ColumnInfo:
356+
"""Row column description object."""
357+
356358
def __init__(
357359
self,
358360
name,
@@ -371,48 +373,41 @@ def __init__(
371373
self.scale = scale
372374
self.null_ok = null_ok
373375

376+
self.fields = (
377+
self.name,
378+
self.type_code,
379+
self.display_size,
380+
self.internal_size,
381+
self.precision,
382+
self.scale,
383+
self.null_ok,
384+
)
385+
374386
def __repr__(self):
375387
return self.__str__()
376388

377389
def __getitem__(self, index):
378-
if index == 0:
379-
return self.name
380-
elif index == 1:
381-
return self.type_code
382-
elif index == 2:
383-
return self.display_size
384-
elif index == 3:
385-
return self.internal_size
386-
elif index == 4:
387-
return self.precision
388-
elif index == 5:
389-
return self.scale
390-
elif index == 6:
391-
return self.null_ok
390+
return self.fields[index]
392391

393392
def __str__(self):
394-
rstr = ", ".join(
395-
[
396-
field
397-
for field in [
393+
str_repr = ", ".join(
394+
filter(
395+
lambda part: part is not None,
396+
[
398397
"name='%s'" % self.name,
399398
"type_code=%d" % self.type_code,
400-
None
401-
if not self.display_size
402-
else "display_size=%d" % self.display_size,
403-
None
404-
if not self.internal_size
405-
else "internal_size=%d" % self.internal_size,
406-
None
407-
if not self.precision
408-
else "precision='%s'" % self.precision,
409-
None if not self.scale else "scale='%s'" % self.scale,
410-
None
411-
if not self.null_ok
412-
else "null_ok='%s'" % self.null_ok,
413-
]
414-
if field
415-
]
399+
"display_size=%d" % self.display_size
400+
if self.display_size
401+
else None,
402+
"internal_size=%d" % self.internal_size
403+
if self.internal_size
404+
else None,
405+
"precision='%s'" % self.precision
406+
if self.precision
407+
else None,
408+
"scale='%s'" % self.scale if self.scale else None,
409+
"null_ok='%s'" % self.null_ok if self.null_ok else None,
410+
],
411+
)
416412
)
417-
418-
return "Column(%s)" % rstr
413+
return "ColumnInfo(%s)" % str_repr

tests/spanner_dbapi/test_cursor.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from unittest import mock
1111

1212
from google.cloud.spanner_dbapi import connect, InterfaceError
13+
from google.cloud.spanner_dbapi.cursor import ColumnInfo
1314

1415

1516
class TestCursor(unittest.TestCase):
@@ -95,3 +96,59 @@ def test_executemany(self):
9596
execute_mock.assert_has_calls(
9697
(mock.call(operation, (1,)), mock.call(operation, (2,)))
9798
)
99+
100+
101+
class TestColumns(unittest.TestCase):
102+
def test_ctor(self):
103+
name = "col-name"
104+
type_code = 8
105+
display_size = 5
106+
internal_size = 10
107+
precision = 3
108+
scale = None
109+
null_ok = False
110+
111+
cols = ColumnInfo(
112+
name,
113+
type_code,
114+
display_size,
115+
internal_size,
116+
precision,
117+
scale,
118+
null_ok,
119+
)
120+
121+
self.assertEqual(cols.name, name)
122+
self.assertEqual(cols.type_code, type_code)
123+
self.assertEqual(cols.display_size, display_size)
124+
self.assertEqual(cols.internal_size, internal_size)
125+
self.assertEqual(cols.precision, precision)
126+
self.assertEqual(cols.scale, scale)
127+
self.assertEqual(cols.null_ok, null_ok)
128+
self.assertEqual(
129+
cols.fields,
130+
(
131+
name,
132+
type_code,
133+
display_size,
134+
internal_size,
135+
precision,
136+
scale,
137+
null_ok,
138+
),
139+
)
140+
141+
def test___get_item__(self):
142+
fields = ("col-name", 8, 5, 10, 3, None, False)
143+
cols = ColumnInfo(*fields)
144+
145+
for i in range(0, 7):
146+
self.assertEqual(cols[i], fields[i])
147+
148+
def test___str__(self):
149+
cols = ColumnInfo("col-name", 8, None, 10, 3, None, False)
150+
151+
self.assertEqual(
152+
str(cols),
153+
"ColumnInfo(name='col-name', type_code=8, internal_size=10, precision='3')",
154+
)

0 commit comments

Comments
 (0)