Este sitio utiliza cookies de Google para prestar sus servicios y analizar su tráfico. Tu dirección IP y user-agent se comparten con Google, junto con las métricas de rendimiento y de seguridad, para garantizar la calidad del servicio, generar estadísticas de uso y detectar y solucionar abusos.Más información

View site in english Ir a la página de inicio Contacta conmigo
sábado, 2 de abril de 2016

Aplicación DBTextFinder, ejemplos de conectores

En este post vamos a ver las estructuras de datos y el interfaz necesarios para desarrollar conectores para cualquier base de datos para agregar al programa DBTextFinder, una herramienta para encontrar texto en los registros, procedimientos almacenados y vistas. También puedes descargar ejemplos de código, desarrollados con Microsoft Visual Studio 2013, con los conectores para SQL Server, Oracle 12c y MySQL.

Este post está relacionado con el artículo aplicación DBTextFinder para buscar texto en bases de datos.

Aquí podéis descargar el código del conector SQL Server, descargar el proyecto para el conector MySQL y descargar el código del proyecto del conector Oracle.

Todos los proyectos hacen referencia a la librería de clases DBTFCommons.dll, en la que se encuentran las definiciones de las clases e interfaces utilizados por todas ellas. Esta librería se instala junto con el programa.

Para implementar un conector con una determinada base de datos, solamente es necesario implementar un interfaz. A continuación revisaremos dicho interfaz y una serie de clases necesarias para la comunicación con la aplicación.

Clases de datos utilizadas por DBTextFinder

Todas las clases que se utilizan para intercambio de datos entre la aplicación y los conectores se encuentran en el espacio de nombres DBTFCommons.Data.

Enumeración SearchScope

Con esta enumeración indicamos el ámbito al que pertenecen los objetos de la base de datos que podemos seleccionar, existen tres valores diferentes:

  • Tables: tablas y vistas.
  • StoredProcs: procedimientos almacenados, funciones, disparadores, código de las vistas y, en el caso de Oracle, paquetes.
  • All: todos los objetos de la base de datos.

Clase ConnectionData

Esta clase contiene los datos necesarios para la conexión:

public class ConnectionData
{
public string StringConnection { get; set; }
public SearchScope Scope { get; set; }
}

StringConnection es la cadena de conexión con la base de datos, que debe construir el conector. Scope se utiliza para configurar el tipo de objetos sobre los que vamos a trabajar.

Clase ConnectionOptions

Esta clase está relacionada con el cuadro de diálogo utilizado por la aplicación para configurar las conexiones:

Cuadro de diálogo administrador de conexiones
Cuadro de diálogo Administrador de conexiones

public class ConnectionOptions
{
public bool SwowInitialCatalog { get; set; }
public bool ShowWindowsAuthentication { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string DataSource { get; set; }
public string InitialCatalog { get; set; }
public bool WindowsAuthentication { get; set; }
public string StringConnection { get; set; }
public string ProviderName { get; set; }
public string Error { get; set; }
public string Description { get; set; }
}

ShowInitialCatalog permite ocultar el cuadro de texto Catálogo, ShowWindowsAuthentication tiene el mismo uso para ocultar la autenticación de Windows. Username y Password contienen el nombre de usuario y la contraseña para la conexión. DataSource es la dirección del servidor, e InitialCatalog el esquema o la base de datos a la cual accedemos (dependiendo del conector). WindowsAuthentication se usa para configurar el acceso utilizando la autenticación integrada de Windows, StringConnection es la cadena de conexión con la base de datos. ProviderName es el nombre del proveedor de acceso, que en este caso será el nombre del tipo del conector.

En la propiedad Error se pueden devolver los mensajes de error producidos al probar la conexión, y Description es la descripción del conector que será mostrada al usuario en el desplegable Conector.

Clase FieldData

Esta clase se utiliza para almacenar datos referentes a un campo de una tabla en el cual se ha encontrado una coincidencia con el texto buscado:

public class FieldData : IComparable<FieldData>, IEquatable<FieldData>
{
public string Name { get; set; }
public string Value { get; set; }
public bool Selected { get; set; }
public string ReplaceEx { get; set; }
public int CompareTo(FieldData other);
public bool Equals(FieldData other);
}

Name contiene el nombre del campo y Value su valor original. Selected se utiliza para indicar si el campo ha sido seleccionado por el usuario para una operación de reemplazo. ReplaceEx es la expresión con la que se va a reemplazar la cadena coincidente encontrada.

CompareTo y Equals son la implementación de los interfaces ICOmparable e IEquatable.

Clase ObjectResult

Se utiliza para devolver los resultados de las búsquedas y para indicar los objetos seleccionados para el reemplazo de texto:

public class ObjectResult
{
public string Schema { get; set; }
public string Name { get; set; }
public bool Selected { get; set; }
}

Schema es el esquema al que pertenece el objeto, y Name su nombre. En la propiedad Selected se indica si el objeto está seleccionado por el usuario.

Clase TableResult

Es una extensión de la clase ObjectResult utilizada para devolver resultados en las búsquedas sobre tablas. Contiene varios miembros con datos sobre los diferentes campos de la tabla.

public class TableResult : ObjectResult
{
public TableResult(IEnumerable<FieldData> text, IEnumerable<FieldData>
keys, IEnumerable<FieldData> all);
public FieldData[] TextFields { get; set; }
public FieldData[] KeyFields { get; set; }
public FieldData[] AllFields { get; set; }
public string QueryFields { get; }
public int SelectedCount { get; }
public FieldData GetField(string name);
public void SetValue(string name, string value);
public override string ToString();
}

El constructor acepta tres parámetros, en el parámetro text se le pasa una enumeración con los campos de tipo texto de la tabla, en keys se enumeran los campos que forman la clave primaria, y en all todos los campos de la tabla.

Las propiedades TextFields, KeyFields y AllFields permiten recuperar la información sobre los campos que contienen texto, forman la clave primaria, o de todos los campos de la tabla, respectivamente.

QueryFields es una función que devuelve los campos separados por coma, para construir sentencias SELECT de SQL sobre la tabla.

Con la función GetField podemos recuperar la información de un determinado campo indicando su nombre, y con SetValue cambiar su valor.

La sustitución de ToString se utiliza para mostrar al usuario los datos del registro.

Clase ProcMatch

Los objetos de esta clase almacenan datos sobre las coincidencias encontradas dentro del código de un procedimiento almacenado o una vista.

public class ProcMatch
{
public int Index { get; set; }
public int Length { get; set; }
public bool Selected { get; set; }
public string ReplaceEx { get; set; }
public override string ToString();
}

Index es el índice del primer carácter de la coincidencia dentro del código, y Length su longitud. Con la propiedad Selected se indica si la coincidencia ha sido seleccionada por el usuario. ReplaceEx contiene la cadena de reemplazo, y la sustitución de ToString permite mostrar la coincidencia al usuario.

Enumeración CodeType

Con los valores de esta enumeración indicamos si un determinado texto es el código de un procedimiento almacenado o de una vista, con los valores View o Procedure.

Clase ProcResult

Esta clase extiende los resultados de la búsqueda para el código de los procedimientos y las vistas:

public class ProcResult : ObjectResult
{
public CodeType CodeType { get; set; }
public string ProcedureCode { get; set; }
public ProcMatch[] Matches { get; set; }
public int MatchCount { get; }
public int SelectedCount { get; }
public void AddMatch(ProcMatch pm);
public override string ToString();
}

CodeType se utiliza para determinar si los resultados pertenecen al código de una vista o de un procedimiento, y ProcedureCode contiene el código completo.

Matches es la colección de todas las coincidencias encontradas en el código, y MatchCount devuelve la cuenta de coincidencias encontradas. SelectedCount devuelve el número de coincidencias seleccionadas por el usuario.

AddMatch se utiliza para agregar nuevas coincidencias, y la sustitución de ToString devuelve el nombre del objeto, cualificado con el nombre del esquema al que pertenece.

Interfaces utilizados por la aplicación

Estos interfaces están definidos en el espacio de nombres DBTFCommons.Interfaces.

Interfaz IDBTFSearchCallback

Este interfaz se utiliza para devolver resultados de las búsquedas cuando se utilizan las versiones asíncronas de los métodos del interfaz principal.

public interface IDBTFSearchCallback
{
bool SearchResult(ObjectResult result);
}

El único miembro es la función SearchResult, para pasarle al programa los resultados que se van encontrando. El valor de retorno indica si se debe cancelar la operación.

Interfaz IDBTFConnection

Este es el interfaz que debe implementar el conector. Todas las funciones tienen una versión síncrona y una asíncrona, que realizan la misma función. Las versiones asíncronas deben ir devolviendo los resultados a la aplicación mediante el interfaz IDBTFSearchCallback comentado anteriormente.

public interface IDBTFConnection
{
IDBTFSearchCallback Callback { get; set; }
ConnectionOptions GetConnectionOptions();
Task<ConnectionOptions> GetConnectionOptionsAsync();
ConnectionOptions ParseConnectionString(string strconn);
Task<ConnectionOptions> ParseConnectionStringAsync(string strconn);
ConnectionOptions ValidateConnectionOptions(ConnectionOptions conntest);
Task<ConnectionOptions> ValidateConnectionOptionsAsync(ConnectionOptions
conntest);
string[] GetSchemas(ConnectionData connection);
Task<string[]> GetSchemasAsync(ConnectionData connection);
string[] GetTables(ConnectionData connection, string schema);
Task<string[]> GetTablesAsync(ConnectionData connection, string schema);
string[] GetViews(ConnectionData connection, string schema);
Task<string[]> GetViewsAsync(ConnectionData connection, string schema);
string[] GetProcedures(ConnectionData connection, string schema);
Task<string[]> GetProceduresAsync(ConnectionData connection, string
schema);
ObjectResult[] Search(ConnectionData connection, string tables, string
views, string procedures, string searchexpr, bool ignorecase);
Task SearchAsync(ConnectionData connection, string tables, string views,
string procedures, string searchexpr, bool ignorecase);
void Replace(ConnectionData connection, ObjectResult result, string
searchexpr, bool ignorecase);
Task ReplaceAsync(ConnectionData connection, ObjectResult result, string
searchexpr, bool ignorecase);
void Delete(ConnectionData connection, ObjectResult result);
Task DeleteAsync(ConnectionData connection, ObjectResult result);
}

La aplicación proporcionará en la propiedad Callback un IDBTFSearchCallback apropiado para devolver los resultados de la búsqueda en las operaciones asíncronas.

Con la función GetConnectionOptions devolveremos la configuración de la conexión apropiada para nuestro conector. ParseConnectionString se utiliza para extraer los datos de configuración de la conexión de una cadena de conexión y ValidateConnectionOptions para realizar un test de conexión con las opciones seleccionadas por el usuario.

Para obtener el listado de objetos de la base de datos, debemos implementar las funciones GetSchemas, que devuelve los esquemas, GetTables, para devolver la lista de nombres de tablas, GetViews, para las vistas, y GetProcedures para los procedimientos almacenados, funciones y disparadores.

Search inicia una búsqueda en la conexión especificada. Como parámetros tenemos los datos para la conexión en connection, en tables se pasarán los nombres de las tablas separados por comas. Estos nombres irán cualificados con el nombre del esquema al que pertenecen. En views se pasarán los nombres de las vistas con el mismo formato y en procedures los procedimientos. searchexpr será la expresión de búsqueda, e ignorecase indicará si debemos diferenciar entre mayúsculas y minúsculas.

Replace realiza la acción de reemplazar texto dentro de un determinado resultado de la búsqueda, que se pasará en el parámetro result. searchexpr e ignorecase tienen el mismo significado que en la función Search.

Por último, Delete permite eliminar registros, procedimientos y vistas, según el resultado pasado en el parámetro result.

Comentarios (0):
* (Su comentario será publicado después de la revisión)

E-Mail


Nombre


Web


Mensaje


CAPTCHA
Change the CAPTCHA codeSpeak the CAPTCHA code