Skip to content

Commit 6b1d99a

Browse files
committed
Provide a way for SqlCertificateDatabase subclasses to override "LIMIT" keyword
1 parent 2f4e160 commit 6b1d99a

File tree

2 files changed

+27
-27
lines changed

2 files changed

+27
-27
lines changed

MimeKit/Cryptography/SQLServerCertificateDatabase.cs

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -243,33 +243,16 @@ protected override void RemoveIndex (DbConnection connection, string tableName,
243243
}
244244

245245
/// <summary>
246-
/// Gets the database command to select the record matching the specified certificate.
246+
/// Limit the query results to a single record.
247247
/// </summary>
248248
/// <remarks>
249-
/// Gets the database command to select the record matching the specified certificate.
249+
/// Modifies the SQL <c>SELECT</c> <paramref name="query"/> to limit the query results to a single record.
250250
/// </remarks>
251-
/// <returns>The database command.</returns>
252-
/// <param name="connection">The database connection.</param>
253-
/// <param name="certificate">The certificate.</param>
254-
/// <param name="fields">The fields to return.</param>
255-
protected override DbCommand GetSelectCommand (DbConnection connection, X509Certificate certificate, X509CertificateRecordFields fields)
251+
/// <param name="query">A <see cref="StringBuilder"/> containing an SQL <c>SELECT</c> query.</param>
252+
/// <returns>A modified SQL query that will limit the results to a single record.</returns>
253+
protected override StringBuilder LimitToOne (StringBuilder query)
256254
{
257-
var fingerprint = certificate.GetFingerprint ().ToLowerInvariant ();
258-
var serialNumber = certificate.SerialNumber.ToString ();
259-
var issuerName = certificate.IssuerDN.ToString ();
260-
var command = CreateCommand ();
261-
var query = CreateSelectQuery (fields).Replace ("SELECT", "SELECT top 1");
262-
263-
// FIXME: Is this really the best way to query for an exact match of a certificate?
264-
query = query.Append (" WHERE ISSUERNAME = @ISSUERNAME AND SERIALNUMBER = @SERIALNUMBER AND FINGERPRINT = @FINGERPRINT");
265-
command.AddParameterWithValue ("@ISSUERNAME", issuerName);
266-
command.AddParameterWithValue ("@SERIALNUMBER", serialNumber);
267-
command.AddParameterWithValue ("@FINGERPRINT", fingerprint);
268-
269-
command.CommandText = query.ToString ();
270-
command.CommandType = CommandType.Text;
271-
272-
return command;
255+
return query.Insert ("SELECT ".Length, "TOP 1 ");
273256
}
274257

275258
/// <summary>

MimeKit/Cryptography/SqlCertificateDatabase.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,19 @@ string GetParameterName (string columnName)
222222
return parameterName;
223223
}
224224

225+
/// <summary>
226+
/// Limit the query results to a single record.
227+
/// </summary>
228+
/// <remarks>
229+
/// Modifies the SQL <c>SELECT</c> <paramref name="query"/> to limit the query results to a single record.
230+
/// </remarks>
231+
/// <param name="query">A <see cref="StringBuilder"/> containing an SQL <c>SELECT</c> query.</param>
232+
/// <returns>A modified SQL query that will limit the results to a single record.</returns>
233+
protected virtual StringBuilder LimitToOne (StringBuilder query)
234+
{
235+
return query.Append (" LIMIT 1");
236+
}
237+
225238
/// <summary>
226239
/// Gets the name of an index based on the table and columns that it is built against.
227240
/// </summary>
@@ -400,7 +413,7 @@ void CreateCrlsTable (DbConnection connection, DataTable table)
400413
}
401414

402415
/// <summary>
403-
/// Creates a SELECT query string builder for the specified fields of an X.509 certificate record.
416+
/// Create a SELECT query string builder for the specified fields of an X.509 certificate record.
404417
/// </summary>
405418
/// <remarks>
406419
/// Creates a SELECT query string builder for the specified fields of an X.509 certificate record.
@@ -423,7 +436,7 @@ protected static StringBuilder CreateSelectQuery (X509CertificateRecordFields fi
423436
}
424437

425438
/// <summary>
426-
/// Creates a SELECT query string builder for the specified fields of an X.509 CRL record.
439+
/// Create a SELECT query string builder for the specified fields of an X.509 CRL record.
427440
/// </summary>
428441
/// <remarks>
429442
/// Creates a SELECT query string builder for the specified fields of an X.509 CRL record.
@@ -471,7 +484,9 @@ protected override DbCommand GetSelectCommand (DbConnection connection, X509Cert
471484
query = query.Append (" WHERE ")
472485
.Append (CertificateColumnNames.IssuerName).Append (" = ").Append (issuerNameParameter).Append (" AND ")
473486
.Append (CertificateColumnNames.SerialNumber).Append (" = ").Append (serialNumberParameter).Append (" AND ")
474-
.Append (CertificateColumnNames.Fingerprint).Append (" = ").Append (fingerprintParameter).Append (" LIMIT 1");
487+
.Append (CertificateColumnNames.Fingerprint).Append (" = ").Append (fingerprintParameter);
488+
query = LimitToOne (query);
489+
475490
command.AddParameterWithValue (issuerNameParameter, issuerName);
476491
command.AddParameterWithValue (serialNumberParameter, serialNumber);
477492
command.AddParameterWithValue (fingerprintParameter, fingerprint);
@@ -734,7 +749,9 @@ protected override DbCommand GetSelectCommand (DbConnection connection, X509Crl
734749
var query = CreateSelectQuery (fields).Append (" WHERE ")
735750
.Append (CrlColumnNames.Delta).Append (" = ").Append (deltaParameter).Append (" AND ")
736751
.Append (CrlColumnNames.IssuerName).Append ("= ").Append (issuerNameParameter).Append (" AND ")
737-
.Append (CrlColumnNames.ThisUpdate).Append (" = ").Append (thisUpdateParameter).Append (" LIMIT 1");
752+
.Append (CrlColumnNames.ThisUpdate).Append (" = ").Append (thisUpdateParameter);
753+
query = LimitToOne (query);
754+
738755
var issuerName = crl.IssuerDN.ToString ();
739756
var command = CreateCommand ();
740757

0 commit comments

Comments
 (0)