Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | {2002} added TSQLDBOracleConnectionProperties.LogSQLWithoutValues property |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9490178233b9351022d705e0a3dfb8e8 |
User & Date: | ab 2015-10-16 07:13:40 |
2015-10-16
| ||
08:09 | {2003} updated documentation, mainly about SynDBOracle advanced use check-in: 885dcbab80 user: ab tags: trunk | |
07:13 | {2002} added TSQLDBOracleConnectionProperties.LogSQLWithoutValues property check-in: 9490178233 user: ab tags: trunk | |
06:32 | SynDBOracle: Oracle Wallet support check-in: fd9933dfbb user: pavel.mash tags: trunk | |
Changes to SynDBOracle.pas.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 ... 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 .... 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 .... 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 .... 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 .... 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 .... 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 .... 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 |
/// event triggered when an expired password is detected // - will allow to provide a new password TOnPasswordExpired = function (Sender: TSQLDBConnection; var APassword: RawUTF8): Boolean of object; /// will implement properties shared by native Oracle Client Interface connections TSQLDBOracleConnectionProperties = class(TSQLDBConnectionPropertiesThreadSafe) private FUseWallet: boolean; protected fRowsPrefetchSize: Integer; fBlobPrefetchSize: Integer; fStatementCacheSize: integer; fInternalBufferSize: integer; fEnvironmentInitializationMode: integer; fOnPasswordChanged: TNotifyEvent; fOnPasswordExpired: TOnPasswordExpired; function GetClientVersion: RawUTF8; /// initialize fForeignKeys content with all foreign keys of this DB // - used by GetForeignKey method procedure GetForeignKeys; override; public /// initialize the connection properties // - we don't need a database name parameter for Oracle connection: only ................................................................................ property OnPasswordExpired: TOnPasswordExpired read FOnPasswordExpired write FOnPasswordExpired; /// Password changed event property OnPasswordChanged: TNotifyEvent read FOnPasswordChanged write FOnPasswordChanged; /// the number of prepared statements cached by OCI on the Client side // - is set to 30 by default // - only used if UseCache=true property StatementCacheSize: integer read fStatementCacheSize write fStatementCacheSize; /// Use the Secure External Password Store for Password Credentials // see Oracle documentation http://docs.oracle.com/cd/B28359_01/network.111/b28531/authentication.htm#DBSEG97906 property UseWallet: boolean read FUseWallet write FUseWallet; end; /// implements a direct connection to the native Oracle Client Interface (OCI) TSQLDBOracleConnection = class(TSQLDBConnectionThreadSafe) protected fEnv: pointer; fError: pointer; ................................................................................ end; end; procedure TSQLDBOracleConnection.Connect; var Log: ISynLog; Props: TSQLDBOracleConnectionProperties; mode: ub4; const type_owner_name: RawUTF8 = 'SYS'; type_NymberListName: RawUTF8 = 'ODCINUMBERLIST'; type_Varchar2ListName: RawUTF8 = 'ODCIVARCHAR2LIST'; begin Log := SynDBLog.Enter(self); Disconnect; // force fTrans=fError=fServer=fContext=nil Props := Properties as TSQLDBOracleConnectionProperties; with OCI do try if fEnv=nil then ................................................................................ AttrSet(fContext,OCI_HTYPE_SVCCTX,@Props.fStatementCacheSize,0, OCI_ATTR_STMTCACHESIZE,fError); mode := OCI_STMT_CACHE; end else mode := OCI_DEFAULT; if Props.UserID='SYS' then mode := mode or OCI_SYSDBA; if Props.UseWallet then CheckSession(self,nil,SessionBegin(fContext,fError,fSession,OCI_CRED_EXT,mode),fError) else CheckSession(self,nil,SessionBegin(fContext,fError,fSession,OCI_CRED_RDBMS,mode),fError); Check(self,nil,TypeByName(fEnv,fError,fContext,Pointer(type_owner_name),length(type_owner_name), Pointer(type_NymberListName),length(type_NymberListName),nil,0,OCI_DURATION_SESSION,OCI_TYPEGET_HEADER, fType_numList),fError); Check(self,nil,TypeByName(fEnv,fError,fContext,Pointer(type_owner_name),length(type_owner_name), Pointer(type_Varchar2ListName),length(type_Varchar2ListName),nil,0,OCI_DURATION_SESSION,OCI_TYPEGET_HEADER, fType_strList),fError); if fOCICharSet=0 then begin ................................................................................ end; finally Free; end; fAnsiConvert := TSynAnsiConvert.Engine(CharSetIDToCodePage(fOCICharSet)); end; if Props.UseWallet then Log.Log(sllInfo,'Connected to % using Oracle Wallet with %, codepage % (%/%)', [Props.ServerName,Props.ClientVersion,fAnsiConvert.CodePage, fOCICharSet,OracleCharSetName(fOCICharSet)],self) else Log.Log(sllInfo,'Connected to % as % with %, codepage % (%/%)', [Props.ServerName,Props.UserID,Props.ClientVersion,fAnsiConvert.CodePage, fOCICharSet,OracleCharSetName(fOCICharSet)],self); with NewStatement do try // ORM will send date/time as ISO8601 text -> force encoding Execute('ALTER SESSION SET NLS_DATE_FORMAT=''YYYY-MM-DD-HH24:MI:SS''',false); finally Free; end; with NewStatement do ................................................................................ tmp: RawUTF8; str_val: POCIString; label txt; begin if (fStatement=nil) then raise ESQLDBOracle.CreateUTF8('%.ExecutePrepared without previous Prepare',[self]); with SynDBLog.Add do if sllSQL in Family.Level then Log(sllSQL,SQL,self,2048); fTimeElapsed.ProfileCurrentMethod; ociArraysCount := 0; Env := (Connection as TSQLDBOracleConnection).fEnv; Context := TSQLDBOracleConnection(Connection).fContext; Status := OCI_ERROR; try fRowFetchedEnded := false; ................................................................................ SetLength(oIndicator,fParamCount); SetLength(ociArrays,fParamCount); for i := 0 to fParamCount-1 do if Length(fParams[i].VArray)>0 then begin // 1.2.1. Bind an array as one object case fParams[i].VType of ftInt64: Type_List := (Connection as TSQLDBOracleConnection).fType_numList; ftUTF8: Type_List := (Connection as TSQLDBOracleConnection).fType_strList; else Type_List := nil; end; if Type_List=nil then raise ESQLDBOracle.CreateUTF8( '%.ExecutePrepared: Unsupported array parameter type #%',[self,i+1]); ociArrays[ociArraysCount] := nil; ................................................................................ end; // 2. execute prepared statement if (fColumnCount=0) and (Connection.TransactionCount=0) then // for INSERT/UPDATE/DELETE without a transaction: AutoCommit after execution mode := OCI_COMMIT_ON_SUCCESS else // for SELECT or inside a transaction: wait for an explicit COMMIT mode := OCI_DEFAULT; Status := OCI.StmtExecute((Connection as TSQLDBOracleConnection).fContext, fStatement,fError,fRowCount,0,nil,nil,mode); FetchTest(Status); // error + set fRowCount+fCurrentRow+fRowFetchedCurrent Status := OCI_SUCCESS; // mark OK for fBoundCursor[] below finally for i := 0 to ociArraysCount-1 do OCI.Check(nil,self,OCI.ObjectFree(Env, fError, ociArrays[i], OCI_OBJECTFREE_FORCE), fError); // 3. release and/or retrieve OUT bound parameters |
< < > > | > | | > > > > < | < < | | < < | | | | > > > | > | | | |
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 ... 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 .... 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 .... 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 .... 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 .... 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 .... 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 .... 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 |
/// event triggered when an expired password is detected // - will allow to provide a new password TOnPasswordExpired = function (Sender: TSQLDBConnection; var APassword: RawUTF8): Boolean of object; /// will implement properties shared by native Oracle Client Interface connections TSQLDBOracleConnectionProperties = class(TSQLDBConnectionPropertiesThreadSafe) protected fRowsPrefetchSize: Integer; fBlobPrefetchSize: Integer; fStatementCacheSize: integer; fInternalBufferSize: integer; fEnvironmentInitializationMode: integer; fOnPasswordChanged: TNotifyEvent; fOnPasswordExpired: TOnPasswordExpired; fUseWallet: boolean; fLogSQLWithoutValues: boolean; function GetClientVersion: RawUTF8; /// initialize fForeignKeys content with all foreign keys of this DB // - used by GetForeignKey method procedure GetForeignKeys; override; public /// initialize the connection properties // - we don't need a database name parameter for Oracle connection: only ................................................................................ property OnPasswordExpired: TOnPasswordExpired read FOnPasswordExpired write FOnPasswordExpired; /// Password changed event property OnPasswordChanged: TNotifyEvent read FOnPasswordChanged write FOnPasswordChanged; /// the number of prepared statements cached by OCI on the Client side // - is set to 30 by default // - only used if UseCache=true property StatementCacheSize: integer read fStatementCacheSize write fStatementCacheSize; /// use the Secure External Password Store for Password Credentials // - see Oracle documentation // http://docs.oracle.com/cd/B28359_01/network.111/b28531/authentication.htm#DBSEG97906 property UseWallet: boolean read fUseWallet write fUseWallet; /// by default, will log values within sllSQL unless this propert is TRUE property LogSQLWithoutValues: boolean read fLogSQLWithoutValues write fLogSQLWithoutValues; end; /// implements a direct connection to the native Oracle Client Interface (OCI) TSQLDBOracleConnection = class(TSQLDBConnectionThreadSafe) protected fEnv: pointer; fError: pointer; ................................................................................ end; end; procedure TSQLDBOracleConnection.Connect; var Log: ISynLog; Props: TSQLDBOracleConnectionProperties; mode: ub4; msg: RawUTF8; const type_owner_name: RawUTF8 = 'SYS'; type_NymberListName: RawUTF8 = 'ODCINUMBERLIST'; type_Varchar2ListName: RawUTF8 = 'ODCIVARCHAR2LIST'; type_Credential: array[boolean] of integer = (OCI_CRED_RDBMS,OCI_CRED_EXT); begin Log := SynDBLog.Enter(self); Disconnect; // force fTrans=fError=fServer=fContext=nil Props := Properties as TSQLDBOracleConnectionProperties; with OCI do try if fEnv=nil then ................................................................................ AttrSet(fContext,OCI_HTYPE_SVCCTX,@Props.fStatementCacheSize,0, OCI_ATTR_STMTCACHESIZE,fError); mode := OCI_STMT_CACHE; end else mode := OCI_DEFAULT; if Props.UserID='SYS' then mode := mode or OCI_SYSDBA; CheckSession(self,nil,SessionBegin(fContext,fError,fSession,type_Credential[Props.UseWallet],mode),fError); Check(self,nil,TypeByName(fEnv,fError,fContext,Pointer(type_owner_name),length(type_owner_name), Pointer(type_NymberListName),length(type_NymberListName),nil,0,OCI_DURATION_SESSION,OCI_TYPEGET_HEADER, fType_numList),fError); Check(self,nil,TypeByName(fEnv,fError,fContext,Pointer(type_owner_name),length(type_owner_name), Pointer(type_Varchar2ListName),length(type_Varchar2ListName),nil,0,OCI_DURATION_SESSION,OCI_TYPEGET_HEADER, fType_strList),fError); if fOCICharSet=0 then begin ................................................................................ end; finally Free; end; fAnsiConvert := TSynAnsiConvert.Engine(CharSetIDToCodePage(fOCICharSet)); end; if Props.UseWallet then msg := 'using Oracle Wallet' else msg := 'as '+Props.UserID; Log.Log(sllInfo,'Connected to % % with %, codepage % (%/%)', [Props.ServerName,msg,Props.ClientVersion,fAnsiConvert.CodePage, fOCICharSet,OracleCharSetName(fOCICharSet)],self); with NewStatement do try // ORM will send date/time as ISO8601 text -> force encoding Execute('ALTER SESSION SET NLS_DATE_FORMAT=''YYYY-MM-DD-HH24:MI:SS''',false); finally Free; end; with NewStatement do ................................................................................ tmp: RawUTF8; str_val: POCIString; label txt; begin if (fStatement=nil) then raise ESQLDBOracle.CreateUTF8('%.ExecutePrepared without previous Prepare',[self]); with SynDBLog.Add do if sllSQL in Family.Level then begin if (Connection.Properties as TSQLDBOracleConnectionProperties).LogSQLWithoutValues then tmp := SQL else tmp := SQLWithInlinedParams; Log(sllSQL,tmp,self,2048); end; fTimeElapsed.ProfileCurrentMethod; ociArraysCount := 0; Env := (Connection as TSQLDBOracleConnection).fEnv; Context := TSQLDBOracleConnection(Connection).fContext; Status := OCI_ERROR; try fRowFetchedEnded := false; ................................................................................ SetLength(oIndicator,fParamCount); SetLength(ociArrays,fParamCount); for i := 0 to fParamCount-1 do if Length(fParams[i].VArray)>0 then begin // 1.2.1. Bind an array as one object case fParams[i].VType of ftInt64: Type_List := TSQLDBOracleConnection(Connection).fType_numList; ftUTF8: Type_List := TSQLDBOracleConnection(Connection).fType_strList; else Type_List := nil; end; if Type_List=nil then raise ESQLDBOracle.CreateUTF8( '%.ExecutePrepared: Unsupported array parameter type #%',[self,i+1]); ociArrays[ociArraysCount] := nil; ................................................................................ end; // 2. execute prepared statement if (fColumnCount=0) and (Connection.TransactionCount=0) then // for INSERT/UPDATE/DELETE without a transaction: AutoCommit after execution mode := OCI_COMMIT_ON_SUCCESS else // for SELECT or inside a transaction: wait for an explicit COMMIT mode := OCI_DEFAULT; Status := OCI.StmtExecute(TSQLDBOracleConnection(Connection).fContext, fStatement,fError,fRowCount,0,nil,nil,mode); FetchTest(Status); // error + set fRowCount+fCurrentRow+fRowFetchedCurrent Status := OCI_SUCCESS; // mark OK for fBoundCursor[] below finally for i := 0 to ociArraysCount-1 do OCI.Check(nil,self,OCI.ObjectFree(Env, fError, ociArrays[i], OCI_OBJECTFREE_FORCE), fError); // 3. release and/or retrieve OUT bound parameters |
Changes to SynopseCommit.inc.
1 |
'1.18.2001'
|
| |
1 |
'1.18.2002'
|