Skip to content

Commit c7d0377

Browse files
authored
Support sqlite3 on Linux (#1486)
* SQLite fixes * Support file locking on Linux
1 parent 073eabb commit c7d0377

3 files changed

Lines changed: 45 additions & 34 deletions

File tree

Src/IronPython.SQLite/Cursor.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System;
99
using System.Collections;
1010
using System.Collections.Generic;
11+
using System.Numerics;
1112
using System.Runtime.InteropServices;
1213
using System.Text.RegularExpressions;
1314
using Community.CsharpSqlite;
@@ -44,7 +45,7 @@ public int? rownumber
4445
get { return null; }
4546
}
4647

47-
public long? lastrowid { get; private set; }
48+
public BigInteger? lastrowid { get; private set; }
4849

4950
public object row_factory { get; set; }
5051

@@ -337,7 +338,7 @@ private object fetchOneRow(CodeContext context)
337338
case Sqlite3.SQLITE_INTEGER:
338339
long l = Sqlite3.sqlite3_column_int64(this.statement.st, i);
339340
if(l < int.MinValue || l > int.MaxValue)
340-
converted = l;
341+
converted = (BigInteger)l;
341342
else
342343
converted = (int)l;
343344

Src/IronPython.SQLite/c#sqlite/os_win_c.cs

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static bool isNT()
225225
// sqlite3_os_type = sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ? 2 : 1;
226226
//}
227227
//return sqlite3_os_type == 2;
228-
return Environment.OSVersion.Platform == PlatformID.Win32NT;
228+
return Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Unix;
229229
}
230230
#endif // * SQLITE_OS_WINCE */
231231

@@ -381,7 +381,7 @@ static int getLastErrorMsg(int nBuf, ref string zBuf){
381381
// (LPWSTR) &zTempWide,
382382
// 0,
383383
// 0);
384-
zBuf = Marshal.GetLastWin32Error().ToString();//new Win32Exception( Marshal.GetLastWin32Error() ).Message;
384+
zBuf = HelperMethods.GetLastError().ToString();//new Win32Exception( Marshal.GetLastWin32Error() ).Message;
385385

386386
//if( dwLen > 0 ){
387387
// /* allocate a buffer and convert to UTF8 */
@@ -458,7 +458,7 @@ int iLine /* Source line number where error occurred */
458458
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
459459
iErrno = (int)ERROR_NOT_SUPPORTED;
460460
#else
461-
iErrno = (u32)Marshal.GetLastWin32Error();
461+
iErrno = (u32)HelperMethods.GetLastError();
462462
#endif
463463

464464
//zMsg[0] = 0;
@@ -851,7 +851,7 @@ static int seekWinFile( sqlite3_file id, sqlite3_int64 iOffset )
851851
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
852852
pFile.lastErrno = 1;
853853
#else
854-
pFile.lastErrno = (u32)Marshal.GetLastWin32Error();
854+
pFile.lastErrno = (u32)HelperMethods.GetLastError();
855855
#endif
856856
winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile.zPath);
857857
return 1;
@@ -967,7 +967,7 @@ sqlite3_int64 offset /* Begin reading at this offset */
967967
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
968968
pFile.lastErrno = 1;
969969
#else
970-
pFile.lastErrno = (u32)Marshal.GetLastWin32Error();
970+
pFile.lastErrno = (u32)HelperMethods.GetLastError();
971971
#endif
972972
return winLogError(SQLITE_IOERR_READ, "winRead", pFile.zPath);
973973
}
@@ -1047,7 +1047,7 @@ sqlite3_int64 offset /* Offset into the file to begin writing at */
10471047
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
10481048
id.lastErrno = 1;
10491049
#else
1050-
id.lastErrno = (u32)Marshal.GetLastWin32Error();
1050+
id.lastErrno = (u32)HelperMethods.GetLastError();
10511051
#endif
10521052
if (( id.lastErrno == ERROR_HANDLE_DISK_FULL )
10531053
|| ( id.lastErrno == ERROR_DISK_FULL ))
@@ -1119,7 +1119,7 @@ static int winTruncate( sqlite3_file id, sqlite3_int64 nByte )
11191119
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
11201120
id.lastErrno = 1;
11211121
#else
1122-
id.lastErrno = (u32)Marshal.GetLastWin32Error();
1122+
id.lastErrno = (u32)HelperMethods.GetLastError();
11231123
#endif
11241124
rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile.zPath);
11251125
}
@@ -1250,9 +1250,6 @@ static int getReadLock( sqlite3_file pFile )
12501250
int res = 0;
12511251
if ( isNT() )
12521252
{
1253-
#if FEATURE_RUNTIMEINFORMATION
1254-
Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
1255-
#endif
12561253
res = lockingStrategy.SharedLockFile( pFile, SHARED_FIRST, SHARED_SIZE );
12571254
}
12581255
/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
@@ -1267,7 +1264,7 @@ static int getReadLock( sqlite3_file pFile )
12671264
#endif
12681265
//}
12691266
if (res == 0) {
1270-
pFile.lastErrno = (u32)Marshal.GetLastWin32Error();
1267+
pFile.lastErrno = (u32)HelperMethods.GetLastError();
12711268
}
12721269
/* No need to log a failure to lock */
12731270
return res;
@@ -1299,7 +1296,7 @@ static int unlockReadLock( sqlite3_file pFile )
12991296
}
13001297
#endif
13011298
if (res == 0) {
1302-
pFile.lastErrno = (u32)Marshal.GetLastWin32Error();
1299+
pFile.lastErrno = (u32)HelperMethods.GetLastError();
13031300

13041301
winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile.zPath);
13051302
}
@@ -1403,7 +1400,7 @@ static int winLock( sqlite3_file id, int locktype )
14031400
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
14041401
error = 1;
14051402
#else
1406-
error = (u32)Marshal.GetLastWin32Error();
1403+
error = (u32)HelperMethods.GetLastError();
14071404
#endif
14081405
}
14091406
}
@@ -1423,7 +1420,7 @@ static int winLock( sqlite3_file id, int locktype )
14231420
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
14241421
error = 1;
14251422
#else
1426-
error = (u32)Marshal.GetLastWin32Error();
1423+
error = (u32)HelperMethods.GetLastError();
14271424
#endif
14281425
}
14291426
}
@@ -1445,7 +1442,7 @@ static int winLock( sqlite3_file id, int locktype )
14451442
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
14461443
error = 1;
14471444
#else
1448-
error = (u32)Marshal.GetLastWin32Error();
1445+
error = (u32)HelperMethods.GetLastError();
14491446
#endif
14501447
}
14511448
if ( res != 0 )
@@ -1457,7 +1454,7 @@ static int winLock( sqlite3_file id, int locktype )
14571454
#if SQLITE_SILVERLIGHT
14581455
error = 1;
14591456
#else
1460-
error = (u32)Marshal.GetLastWin32Error();
1457+
error = (u32)HelperMethods.GetLastError();
14611458
#endif
14621459
}
14631460
}
@@ -1499,7 +1496,7 @@ static int winLock( sqlite3_file id, int locktype )
14991496
#if SQLITE_SILVERLIGHT || SQLITE_WINRT
15001497
error = 1;
15011498
#else
1502-
error = (u32)Marshal.GetLastWin32Error();
1499+
error = (u32)HelperMethods.GetLastError();
15031500
#endif
15041501
#if SQLITE_DEBUG
15051502
OSTRACE( "error-code = %d\n", error );
@@ -2621,8 +2618,8 @@ static int winOpen(
26212618

26222619
// /* Convert the filename to the system encoding. */
26232620
zConverted = zUtf8Name;// convertUtf8Filename( zUtf8Name );
2624-
if ( zConverted.StartsWith( "/", StringComparison.Ordinal ) && !zConverted.StartsWith( "//", StringComparison.Ordinal ) )
2625-
zConverted = zConverted.Substring( 1 );
2621+
//if ( zConverted.StartsWith( "/", StringComparison.Ordinal ) && !zConverted.StartsWith( "//", StringComparison.Ordinal ) )
2622+
// zConverted = zConverted.Substring( 1 );
26262623
//if ( String.IsNullOrEmpty( zConverted ) )
26272624
//{
26282625
// return SQLITE_NOMEM;
@@ -2804,7 +2801,7 @@ static int winOpen(
28042801
pFile.lastErrno = 1;
28052802
#else
28062803
// pFile.lastErrno = GetLastError();
2807-
pFile.lastErrno = (u32)Marshal.GetLastWin32Error();
2804+
pFile.lastErrno = (u32)HelperMethods.GetLastError();
28082805
#endif
28092806
winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
28102807
// free(zConverted);
@@ -2982,7 +2979,7 @@ int syncDir /* Not used on win32 */
29822979
if ( rc == SQLITE_OK )
29832980
return rc;
29842981

2985-
error = Marshal.GetLastWin32Error();
2982+
error = HelperMethods.GetLastError();
29862983

29872984
return ( ( rc == INVALID_FILE_ATTRIBUTES )
29882985
&& ( error == ERROR_FILE_NOT_FOUND ) ) ? SQLITE_OK :
@@ -3179,7 +3176,7 @@ StringBuilder zFull /* Output buffer */
31793176
/* If this path name begins with "/X:", where "X" is any alphabetic
31803177
** character, discard the initial "/" from the pathname.
31813178
*/
3182-
if( zRelative[0]=='/' && Char.IsLetter(zRelative[1]) && zRelative[2]==':' ){
3179+
if( zRelative.Length >= 3 && zRelative[0]=='/' && Char.IsLetter(zRelative[1]) && zRelative[2]==':' ){
31833180
zRelative = zRelative.Substring(1);
31843181
}
31853182

@@ -3210,7 +3207,16 @@ StringBuilder zFull /* Output buffer */
32103207
#if WINDOWS_PHONE || SQLITE_SILVERLIGHT || SQLITE_WINRT
32113208
zOut = zRelative;
32123209
#else
3213-
zOut = Path.GetFullPath( zRelative ); // was unicodeToUtf8(zTemp);
3210+
if (Environment.OSVersion.Platform == PlatformID.Unix
3211+
&& zRelative.Length > 2 && zRelative[0] == '~' && (zRelative[1] == '/' || zRelative[1] == '\\'))
3212+
{
3213+
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
3214+
zOut = Path.GetFullPath(home + zRelative.Substring(1));
3215+
}
3216+
else
3217+
{
3218+
zOut = Path.GetFullPath( zRelative ); // was unicodeToUtf8(zTemp);
3219+
}
32143220
#endif
32153221
}
32163222
catch ( Exception e )
@@ -3714,12 +3720,12 @@ public virtual void LockFile( sqlite3_file pFile, long offset, long length )
37143720
#pragma warning restore CA1416 // Validate platform compatibility
37153721
}
37163722

3717-
#if FEATURE_OSPLATFORMATTRIBUTE
3718-
[SupportedOSPlatform("windows")]
3719-
#endif
37203723
public virtual int SharedLockFile( sqlite3_file pFile, long offset, long length )
37213724
{
37223725
#if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE || SQLITE_WINRT)
3726+
#if FEATURE_RUNTIMEINFORMATION
3727+
Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
3728+
#endif
37233729
Debug.Assert( length == SHARED_SIZE );
37243730
Debug.Assert( offset == SHARED_FIRST );
37253731
NativeOverlapped ovlp = new NativeOverlapped();
@@ -3749,17 +3755,16 @@ public virtual void UnlockFile( sqlite3_file pFile, long offset, long length )
37493755
/// </summary>
37503756
private class MediumTrustLockingStrategy : LockingStrategy
37513757
{
3752-
#if FEATURE_OSPLATFORMATTRIBUTE
3753-
[SupportedOSPlatform("windows")]
3754-
#endif
37553758
public override int SharedLockFile( sqlite3_file pFile, long offset, long length )
37563759
{
37573760
#if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE || SQLITE_WINRT)
37583761
Debug.Assert( length == SHARED_SIZE );
37593762
Debug.Assert( offset == SHARED_FIRST );
37603763
try
37613764
{
3765+
#pragma warning disable CA1416 // Validate platform compatibility
37623766
pFile.fs.Lock( offset + pFile.sharedLockByte, 1 );
3767+
#pragma warning restore CA1416 // Validate platform compatibility
37633768
}
37643769
catch ( IOException )
37653770
{
@@ -3776,7 +3781,7 @@ public static bool IsRunningMediumTrust() {
37763781
// placeholder method
37773782
// this is where it needs to check if it's running in an ASP.Net MediumTrust or lower environment
37783783
// in order to pick the appropriate locking strategy
3779-
return false;
3784+
return Environment.OSVersion.Platform == PlatformID.Unix;
37803785
}
37813786

37823787
#if SQLITE_WINRT
@@ -3797,5 +3802,10 @@ public static bool FileExists(string path)
37973802
return exists;
37983803
}
37993804
#endif
3805+
3806+
public static int GetLastError()
3807+
{
3808+
return Marshal.GetLastWin32Error();
3809+
}
38003810
}
38013811
}

Src/IronPython.SQLite/c#sqlite/pager_c.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5023,10 +5023,10 @@ dxReiniter xReinit /* Function to reinitialize pages */
50235023

50245024
/* Open the pager file.
50255025
*/
5026-
if ( !String.IsNullOrEmpty( zFilename ) )
5026+
if ( !String.IsNullOrEmpty( pPager.zFilename ) )
50275027
{
50285028
int fout = 0; /* VFS flags returned by xOpen() */
5029-
rc = sqlite3OsOpen( pVfs, zFilename, pPager.fd, vfsFlags, ref fout );
5029+
rc = sqlite3OsOpen( pVfs, pPager.zFilename, pPager.fd, vfsFlags, ref fout );
50305030
Debug.Assert( 0 == memDb );
50315031
readOnly = ( fout & SQLITE_OPEN_READONLY ) != 0;
50325032

0 commit comments

Comments
 (0)