mimerpy 1.3.2__tar.gz → 1.3.4__tar.gz

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.
Files changed (59) hide show
  1. {mimerpy-1.3.2 → mimerpy-1.3.4}/PKG-INFO +1 -1
  2. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/releasenotes.rst +22 -2
  3. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/_version.py +2 -2
  4. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/cursorPy.py +10 -3
  5. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/mimerapi.py +7 -0
  6. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy.egg-info/PKG-INFO +1 -1
  7. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/testConnection.py +3 -3
  8. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/testCursor.py +22 -3
  9. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/testScrollCursor.py +24 -5
  10. {mimerpy-1.3.2 → mimerpy-1.3.4}/.gitattributes +0 -0
  11. {mimerpy-1.3.2 → mimerpy-1.3.4}/.gitignore +0 -0
  12. {mimerpy-1.3.2 → mimerpy-1.3.4}/LICENSE.txt +0 -0
  13. {mimerpy-1.3.2 → mimerpy-1.3.4}/MANIFEST.in +0 -0
  14. {mimerpy-1.3.2 → mimerpy-1.3.4}/README.rst +0 -0
  15. {mimerpy-1.3.2 → mimerpy-1.3.4}/dist-requirements.txt +0 -0
  16. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/.gitignore +0 -0
  17. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/Makefile +0 -0
  18. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/README.txt +0 -0
  19. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/_static/style.css +0 -0
  20. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/_templates/layout.html +0 -0
  21. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/codeexamples.rst +0 -0
  22. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/conf.py +0 -0
  23. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/datatypes.rst +0 -0
  24. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/dbtest.py +0 -0
  25. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/exceptions.rst +0 -0
  26. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/gettingstarted.rst +0 -0
  27. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/images/mimerhd.png +0 -0
  28. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/images/mimerhd32x32.ico +0 -0
  29. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/images/mimerhd32x32.png +0 -0
  30. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/index.rst +0 -0
  31. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/installationguide.rst +0 -0
  32. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/introduction.rst +0 -0
  33. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/legalnotice.rst +0 -0
  34. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/make_for_windows.bat +0 -0
  35. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/mimerpy.rst +0 -0
  36. {mimerpy-1.3.2 → mimerpy-1.3.4}/doc/userguide.rst +0 -0
  37. {mimerpy-1.3.2 → mimerpy-1.3.4}/pyproject.toml +0 -0
  38. {mimerpy-1.3.2 → mimerpy-1.3.4}/scripts/ebuild.sh +0 -0
  39. {mimerpy-1.3.2 → mimerpy-1.3.4}/scripts/ubuntuAutoRelease.sh +0 -0
  40. {mimerpy-1.3.2 → mimerpy-1.3.4}/scripts/windowsAutoRelease.bat +0 -0
  41. {mimerpy-1.3.2 → mimerpy-1.3.4}/setup.cfg +0 -0
  42. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/__init__.py +0 -0
  43. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/__main__.py +0 -0
  44. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/connectionPy.py +0 -0
  45. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/mimPyErrorCodes.py +0 -0
  46. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/mimPyExceptionHandler.py +0 -0
  47. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/mimPyExceptions.py +0 -0
  48. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/pool.py +0 -0
  49. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy/utils.py +0 -0
  50. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy.egg-info/SOURCES.txt +0 -0
  51. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy.egg-info/dependency_links.txt +0 -0
  52. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy.egg-info/requires.txt +0 -0
  53. {mimerpy-1.3.2 → mimerpy-1.3.4}/src/mimerpy.egg-info/top_level.txt +0 -0
  54. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/__init__.py +0 -0
  55. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/db_config.py +0 -0
  56. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/dropdb.py +0 -0
  57. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/testMimerPool.py +0 -0
  58. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/testMonkey.py +0 -0
  59. {mimerpy-1.3.2 → mimerpy-1.3.4}/tests/testutils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mimerpy
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: Python database interface for Mimer SQL
5
5
  Author-email: Erik Gunne <mimerpy@mimer.com>, Magdalena Boström <mimerpy@mimer.com>, Mimer Information Technology AB <mimerpy@mimer.com>
6
6
  Maintainer-email: Mimer Information Technology AB <mimerpy@mimer.com>
@@ -56,9 +56,29 @@ Major changes:
56
56
 
57
57
  MimerPy Version 1.3.2
58
58
  ---------------------
59
- MimerPy version 1.3.2 is a minor buggfix release that fix a problem with datetime in Python version 3.9 and older
59
+ MimerPy version 1.3.2 is a minor buggfix release that fix a problem with datetime in Python version 3.9 and older.
60
60
 
61
- Major changes:
61
+ Minor changes:
62
62
 
63
63
  * Use a safe datetime and time parser
64
64
  * On Python 3.6, use dateutil module to parse ISO 8601 date strings
65
+
66
+ MimerPy Version 1.3.3
67
+ ---------------------
68
+ MimerPy version 1.3.3 is a buggfix release that correct the behavior for fetchone()
69
+
70
+ Major changes:
71
+
72
+ * fetchone() now returns None when no more rows are available, in accordance with the DB-API 2.0 specification.
73
+
74
+ MimerPy Version 1.3.4
75
+ ---------------------
76
+ MimerPy version 1.3.4 is a minor feature release that addes the optional cursor.lastrowid
77
+
78
+ Minoe changes:
79
+
80
+ * cursor.lastrowid now return the auto generated primary key when doing and insert. The following conditions have to be met, otherwise `None` is returned:
81
+
82
+ * The primary key must have a default value with `NEXT VALUE FOR <sequence>`
83
+ * The primary key must be a single integer type column
84
+ * No value must be given for the primary key when inserting the row
@@ -1,4 +1,4 @@
1
1
  # file generated by setuptools_scm
2
2
  # don't change, don't track in version control
3
- __version__ = version = '1.3.2'
4
- __version_tuple__ = version_tuple = (1, 3, 2)
3
+ __version__ = version = '1.3.4'
4
+ __version_tuple__ = version_tuple = (1, 3, 4)
@@ -308,6 +308,7 @@ class Cursor:
308
308
  self.__session = session
309
309
  self.__statement = None
310
310
  self.__mimcursor = False
311
+ self.lastrowid = None
311
312
 
312
313
  def __enter__(self):
313
314
  self.__check_if_open()
@@ -323,7 +324,7 @@ class Cursor:
323
324
  def __next__(self):
324
325
  self.__check_if_open()
325
326
  return_value = self.fetchone()
326
- if return_value == []:
327
+ if return_value is None:
327
328
  raise StopIteration
328
329
  return return_value
329
330
 
@@ -356,6 +357,7 @@ class Cursor:
356
357
  self.__check_if_open()
357
358
  self.__check_for_transaction()
358
359
  parameter_markers = ()
360
+ self.lastrowid = None
359
361
 
360
362
  # I would like to look over this at some point, the type control is not ideal - Erik 2018-10
361
363
  if (len(arg) > 1):
@@ -457,6 +459,9 @@ class Cursor:
457
459
  rc_value = mimerapi.mimerExecute(self.__statement)
458
460
  self.__check_mimerapi_error(rc_value, self.__statement)
459
461
  self.rowcount = rc_value
462
+ rc, val = mimerapi.mimerGetSequenceInt64(self.__statement)
463
+ if rc == 0 and val != 0:
464
+ self.lastrowid = val
460
465
  else:
461
466
  # Return value of mimerColumnCount > 0 implies a query with a
462
467
  # result set.
@@ -508,6 +513,7 @@ class Cursor:
508
513
  self.rowcount = 0
509
514
  rc_value = 0
510
515
  values = []
516
+ self.lastrowid = None
511
517
 
512
518
  if isinstance(params, GeneratorType):
513
519
  tmp_params = []
@@ -609,7 +615,7 @@ class Cursor:
609
615
 
610
616
  # Return value of mimerFetch == 100 implies end of result set
611
617
  if (rc_value == 100):
612
- return []
618
+ return None
613
619
 
614
620
  for cur_column in range(1, self._number_of_columns + 1):
615
621
  func_tuple = get_funcs[self._column_type[cur_column - 1]
@@ -794,6 +800,7 @@ class ScrollCursor(Cursor):
794
800
  super(ScrollCursor, self).__init__(connection, session)
795
801
  self.__result_set = None
796
802
  self.rownumber = None
803
+ self.lastrowid = None
797
804
 
798
805
  def execute(self, *arg):
799
806
  """
@@ -835,7 +842,7 @@ class ScrollCursor(Cursor):
835
842
  values = values + self.__result_set[self.rownumber]
836
843
  self.rownumber = self.rownumber + 1
837
844
  except IndexError:
838
- return []
845
+ return None
839
846
  return values
840
847
 
841
848
  def fetchmany(self, *arg):
@@ -256,6 +256,8 @@ _MimerSetBoolean = _bind('MimerSetBoolean', c_int32, MimerStatement,
256
256
  _MimerGetBoolean = _bind('MimerGetBoolean', c_int32, MimerStatement, c_int16)
257
257
  _MimerGetUUID = _bind('MimerGetUUID', c_int32, MimerStatement, c_int16, c_void_p)
258
258
  _MimerSetUUID = _bind('MimerSetUUID', c_int32, MimerStatement, c_int16, c_void_p)
259
+ _MimerGetSequenceInt64 = _bind('MimerGetSequenceInt64', c_int32, MimerStatement, POINTER(c_int64))
260
+
259
261
  # GIS bindings
260
262
  class MimerGisLocation(ctypes.Structure):
261
263
  _fields_ = [("latitude", c_double), ("longitude", c_double)]
@@ -482,6 +484,11 @@ def mimerGetFloat(statement_ptr: int, column_number: int):
482
484
  rc = _MimerGetFloat(MimerStatement(statement_ptr), _arg_i16(column_number), byref(out))
483
485
  return (int(rc), float(out.value))
484
486
 
487
+ def mimerGetSequenceInt64(statement_ptr: int):
488
+ out = c_int64()
489
+ rc = _MimerGetSequenceInt64(MimerStatement(statement_ptr), byref(out))
490
+ return (int(rc), int(out.value))
491
+
485
492
  def mimerSetInt32(statement_ptr: int, parameter_number: int, value):
486
493
  sp = int(statement_ptr)
487
494
  if value is None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mimerpy
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: Python database interface for Mimer SQL
5
5
  Author-email: Erik Gunne <mimerpy@mimer.com>, Magdalena Boström <mimerpy@mimer.com>, Mimer Information Technology AB <mimerpy@mimer.com>
6
6
  Maintainer-email: Mimer Information Technology AB <mimerpy@mimer.com>
@@ -320,7 +320,7 @@ class TestConnectionMethods(unittest.TestCase):
320
320
  a.close()
321
321
 
322
322
  b = self.tstcon.execute("select * from bob6")
323
- self.assertEqual(b.fetchone(), [])
323
+ self.assertIsNone(b.fetchone())
324
324
  b.close()
325
325
 
326
326
  def test_autocommit(self):
@@ -363,7 +363,7 @@ class TestConnectionMethods(unittest.TestCase):
363
363
  a.close()
364
364
 
365
365
  b = self.tstcon.execute("select * from bob63")
366
- self.assertEqual(b.fetchone(), [])
366
+ self.assertIsNone(b.fetchone())
367
367
  b.close()
368
368
 
369
369
  def test_autocommit_4(self):
@@ -376,7 +376,7 @@ class TestConnectionMethods(unittest.TestCase):
376
376
  a.close()
377
377
 
378
378
  b = self.tstcon.execute("select * from bob64")
379
- self.assertEqual(b.fetchone(), [])
379
+ self.assertIsNone(b.fetchone())
380
380
  b.close()
381
381
 
382
382
 
@@ -670,7 +670,7 @@ class TestCursorMethods(unittest.TestCase):
670
670
  c.execute("insert into bob556 values (3)")
671
671
  self.tstcon.rollback()
672
672
  c.execute("select * from bob556")
673
- self.assertEqual(c.fetchone(), [])
673
+ self.assertIsNone(c.fetchone())
674
674
 
675
675
  def test_invalid_sequence_insert(self):
676
676
  with self.tstcon.cursor() as c:
@@ -869,7 +869,7 @@ class TestCursorMethods(unittest.TestCase):
869
869
  c.execute("SELECT * from jonNone")
870
870
  for i in range(1, 10):
871
871
  c.fetchone()
872
- self.assertEqual(c.fetchone(), [])
872
+ self.assertIsNone(c.fetchone())
873
873
 
874
874
  def test_empty_sequence_is_returned_many(self):
875
875
  with self.tstcon.cursor() as c:
@@ -2060,7 +2060,7 @@ create table longboi (c1 char(10),
2060
2060
  a.close()
2061
2061
 
2062
2062
 
2063
- if (mimerapi._level == 2):
2063
+ if (mimerapi._level >= 2):
2064
2064
  def test_datatype_float_p(self):
2065
2065
  with self.tstcon.cursor() as c:
2066
2066
  c.execute("create table floatptable (c1 FLOAT(5)) in pybank")
@@ -2089,6 +2089,25 @@ create table longboi (c1 char(10),
2089
2089
  #with self.assertRaises(ProgrammingError):
2090
2090
  c.execute("insert INTO jondecimal4 VALUES (?)", (floatnum))
2091
2091
 
2092
+ def test_lastrowid(self):
2093
+ a = mimerpy.connect(**db_config.TSTUSR)
2094
+ b = a.cursor()
2095
+ self.assertIsNone(b.lastrowid)
2096
+ b.execute("create unique sequence lastrowid_seq in pybank")
2097
+ self.assertIsNone(b.lastrowid)
2098
+ b.execute("create table lastrowidtable (id INTEGER DEFAULT NEXT VALUE FOR lastrowid_seq, name NVARCHAR(20)) in pybank")
2099
+ self.assertIsNone(b.lastrowid)
2100
+ b.execute("insert into lastrowidtable(name) values (:a)", ('bob'))
2101
+ self.assertEqual(b.lastrowid, 1)
2102
+ b.execute("insert into lastrowidtable(name) values (:a)", ('frank'))
2103
+ self.assertEqual(b.lastrowid, 2)
2104
+ b.executemany("insert into lastrowidtable(name) values (:a)", [('karl'), ('alice')])
2105
+ self.assertIsNone(b.lastrowid)
2106
+ b.execute("select * from lastrowidtable")
2107
+ self.assertIsNone(b.lastrowid)
2108
+ r = b.fetchall()
2109
+ a.close()
2110
+
2092
2111
 
2093
2112
  if __name__ == '__main__':
2094
2113
  unittest.TestLoader.sortTestMethodsUsing = None
@@ -670,7 +670,7 @@ class TestScrollCursorMethods(unittest.TestCase):
670
670
  c.execute("SELECT * from jonNone")
671
671
  for i in range(1,10):
672
672
  c.fetchone()
673
- self.assertEqual(c.fetchone(), [])
673
+ self.assertIsNone(c.fetchone())
674
674
 
675
675
  def test_empty_sequence_is_returned_many(self):
676
676
  with self.tstcon.cursor(scrollable = True) as c:
@@ -1033,7 +1033,7 @@ class TestScrollCursorMethods(unittest.TestCase):
1033
1033
  self.assertEqual(c.fetchone(), (9, 'bob9'))
1034
1034
  self.assertEqual(c.fetchone(), (10, 'bob10'))
1035
1035
  self.assertEqual(c.fetchone(), (11, 'bob11'))
1036
- self.assertEqual(c.fetchone(), [])
1036
+ self.assertIsNone(c.fetchone())
1037
1037
 
1038
1038
  def test_fetchone_rownumber(self):
1039
1039
  with self.tstcon.cursor(scrollable = True) as c:
@@ -1049,7 +1049,7 @@ class TestScrollCursorMethods(unittest.TestCase):
1049
1049
  self.assertEqual(c.rownumber, 2)
1050
1050
  self.assertEqual(c.fetchone(), (11, 'bob11'))
1051
1051
  self.assertEqual(c.rownumber, 3)
1052
- self.assertEqual(c.fetchone(), [])
1052
+ self.assertIsNone(c.fetchone())
1053
1053
  self.assertEqual(c.rownumber, 3)
1054
1054
 
1055
1055
  def test_fetchmany_rownumber(self):
@@ -1107,7 +1107,7 @@ class TestScrollCursorMethods(unittest.TestCase):
1107
1107
  [(6, 'bob6'),(7, 'bob7'),(8, 'bob8'),
1108
1108
  (9, 'bob9'),(10, 'bob10')])
1109
1109
  self.assertEqual(c.rownumber, 10)
1110
- self.assertEqual(c.fetchone(), [])
1110
+ self.assertIsNone(c.fetchone())
1111
1111
  self.assertEqual(c.fetchmany(21), [])
1112
1112
  self.assertEqual(c.fetchall(), [])
1113
1113
 
@@ -1224,7 +1224,7 @@ class TestScrollCursorMethods(unittest.TestCase):
1224
1224
  self.tstcon.rollback()
1225
1225
  c.execute("select * from bobnoselect")
1226
1226
  r = c.fetchone()
1227
- self.assertEqual(len(r), 0)
1227
+ self.assertIsNone(r)
1228
1228
 
1229
1229
  def test_no_select2(self):
1230
1230
  with self.tstcon.cursor(scrollable = True) as c:
@@ -1253,6 +1253,25 @@ class TestScrollCursorMethods(unittest.TestCase):
1253
1253
  with self.assertRaises(ProgrammingError):
1254
1254
  c.next()
1255
1255
 
1256
+ def test_lastrowid(self):
1257
+ a = mimerpy.connect(**db_config.TSTUSR)
1258
+ b = a.cursor()
1259
+ self.assertIsNone(b.lastrowid)
1260
+ b.execute("create unique sequence lastrowidscroll_seq in pybank")
1261
+ self.assertIsNone(b.lastrowid)
1262
+ b.execute("create table lastrowidscroll (id INTEGER DEFAULT NEXT VALUE FOR lastrowidscroll_seq, name NVARCHAR(20)) in pybank")
1263
+ self.assertIsNone(b.lastrowid)
1264
+ b.execute("insert into lastrowidscroll(name) values (:a)", ('bob'))
1265
+ self.assertEqual(b.lastrowid, 1)
1266
+ b.execute("insert into lastrowidscroll(name) values (:a)", ('frank'))
1267
+ self.assertEqual(b.lastrowid, 2)
1268
+ b.executemany("insert into lastrowidscroll(name) values (:a)", [('karl'), ('alice')])
1269
+ self.assertIsNone(b.lastrowid)
1270
+ b.execute("select * from lastrowidscroll")
1271
+ self.assertIsNone(b.lastrowid)
1272
+ r = b.fetchall()
1273
+ a.close()
1274
+
1256
1275
  if __name__ == '__main__':
1257
1276
  unittest.TestLoader.sortTestMethodsUsing = None
1258
1277
  unittest.main()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes