Roque
Rueda
Mi hermano me solicito que le creara un sitio web para
venta de ropa así que para apoyarle he decidido crear un sitio web ASP .net en
donde el pueda promocionar las ventas.
En el post pasado se
creó la estructura de base de datos pero ahora la base de datos usualmente debe
contener restricciones para los datos, esto con la finalidad de asegurar que
los datos almacenados sean correctos, lo primero que vamos a hacer es crear los
scripts para indicar las reglas de los datos en las tablas que tenemos.
Primero tomaremos la
tabla Client la cual no pensaremos
de momento en sus relaciones si no únicamente en los valores que vamos a
permitir sean almacenados.
En este caso debido a
que deseamos utilizar una función para validar los datos del email de los
clientes y SQLServer no contiene por defecto el soporte para expresiones
regulares vamos a crear una función y la vamos a utilizar cuando sea requerido.
Para esto vamos a
crear presionar "New Query" lo que nos muestra una ventana donde se
pueden ejecutar comandos SQL.
Vamos a escribir en
nuestra ventana el siguiente código:
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO
Aquí estamos
modificando que se habilite clr que es la capacidad para la ejecución de
funciones hechas a mano. Ahora para ejecutar todo el script vamos a presionar
F5 con lo que se nos va a mostrar algo como lo siguiente:
Ahora se debe crear el
código del proyecto para esto vamos a crear un proyecto de biblioteca de clases
y vamos a agregar los métodos que serán las funciones SQL en el futuro (estos
métodos deben ser estáticos). Vamos a crear un nuevo proyecto en visual studio
iniciando como siempre con una solucion en blanco.
La cual vamos a llamar
RegexSqlFunctions, una vez que se nos muestre nuestro explorador de soluciones
vamos a agregar un nuevo proyecto.
Vamos a agregar el
proyecto de biblioteca de clases y lo llamaremos RegexFuntions. Quedando
nuestro explorador de soluciones de la siguiente manera:
Ahora lo que debemos
agregar también ya que estamos siguiendo la forma de trabajo TDD (desarrollo dirigido por pruebas) es
contar con otro proyecto el cual será un proyecto de pruebas el cual va a
asegurar los resultados de la ejecución de nuestro código.
Ahora bien debemos
agregar la referencia a nuestro proyecto de pruebas una vez hecho esto vamos a
poder llamar realizar pruebas al código de nuestra biblioteca de clases. También
vamos a cambiar el nombre de las clases de nuestros 2 proyectos para que tengan
un mejor significado. Vamos a nombrar Regex a la clase de nuestra biblioteca de
clases y RegexTest a la de nuestro proyecto de pruebas.
Debemos agregar la
referencia a System.Data, donde vamos a agregar los siguientes espacios de nombres.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Server;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Ahora vamos a pensar en nuestra prueba para esto vamos
a pensar en el valor de retorno de nuestro método, para este caso True o False
sin embargo para SQLServer no se puede utilizar un boolean de C# se debe
retornar el tipo SqlBoolean el cual representa un verdadero o falso para
SQLServer.
Ahora el codigo para nuestra pruena quedara como se
muestra a continuacion:
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Text.RegularExpressions; using Microsoft.SqlServer.Server; using Microsoft.VisualStudio.TestTools.UnitTesting; using RegexFunctions; namespace RegexFunctionTest { [TestClass] public class RegexTest { [TestMethod] public void MatchTest() { // Arrange var expected = new SqlBoolean(true); string value = "skaroque@gmail.com"; string pattern = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|" + @"(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"; // Act SqlBoolean actual = SQLRegex.MatchRegex(value, pattern); // Assert Assert.AreEqual(expected, actual); } } }
Como se puede ver este método no existe también nótese que se está accediendo a él de forma estática y le estamos dando los nombres a los parámetros que deseamos que aparezcan en la firma del método; todo esto nos ayuda a que visual studio nos genere el método con la firma adecuada. Para que nos genere el código vamos a hacer clic derecho sobre el método. Y seleccionamos Generate method stub.Ahora nuestra clase la he renombrado como SQLRegex para eviar la colicion de nombres y he agregado el código para la clase con lo siguiente:
/* * Copyright 2013 Roque Rueda. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.SqlTypes; using System.Text.RegularExpressions; namespace RegexFunctions { ////// Regex function for SQLServer. /// public partial class SQLRegex { ////// Evaluates if the value parameter match with the pattern. /// /// The string value to ve evaluated. /// Pattern that is going to be find in the value. ////// [Microsoft.SqlServer.Server.SqlFunction] public static SqlBoolean MatchRegex(SqlString value, SqlString pattern) { return new SqlBoolean(Regex.IsMatch(value.Value, pattern.Value)); } } } indicating if the value match the pattern.
Ahora vamos a ejecutar
las pruebas a nuestra clase. Para verificar su correcto o incorrecto
funcionamiento. Para esto agregamos el siguiente método y ejecutamos las
pruebas.
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Text.RegularExpressions; using Microsoft.SqlServer.Server; using Microsoft.VisualStudio.TestTools.UnitTesting; using RegexFunctions; namespace RegexFunctionTest { [TestClass] public class RegexTest { [TestMethod] public void MatchTest() { // Arrange SqlBoolean expected = new SqlBoolean(true); string value = "skaroque@gmail.com"; string pattern = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|" + @"(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"; // Act SqlBoolean actual = SQLRegex.MatchRegex(value, pattern); // Assert Assert.AreEqual(expected, actual); } [TestMethod] public void NotMatchTest() { // Arrange SqlBoolean expected = new SqlBoolean(false); string vale = "skaroquegmail.com"; string pattern = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|" + @"(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"; //Act SqlBoolean actual = SQLRegex.MatchRegex(vale, pattern); // Assert Assert.AreEqual (expected, actual); } } }
Verificamos que las
pruebas sean satisfactorias. Ahora para que nuestra biblioteca sea registrada
debe estar en el framework 3.5 por lo que vamos a hacer clic derecho en nuestro
proyecto y vamos a seleccionar propiedades del menú desplegable. Y
modificaremos del framework 4.5 al 3.5.
Ahora que nuestras
pruebas son satisfactorias vamos a proceder a registrar nuestra funcion clr
para esto vamos a ejecutar el siguiente comando en SQLServer:
CREATE ASSEMBLY
-- name of the assembly from SQL
RegexFunctions
AUTHORIZATION
[dbo]
-- full path of the aseembly
from 'C:\Projects\SqlServer\RegexFunctions.dll'
WITH PERMISSION_SET =
SAFE
Y si todo es correcto
debemos obtener el siguiente mensaje de respuesta:
Command(s)
completed successfully.
Esto nos indica que
nuestra biblioteca ya se registro en SQLServer (Para borrar el registro de
nuestra biblioteca debemos ejecutar un "drop asembly <nombre>").
Ahora solo debemos crear la función (liga nuestro método de la dll a una
función de sql) para lo cual vamos a ejecutar el siguiente script:
-- function name like an alias
CREATE FUNCTION RegExp(@Text
nvarchar(max), @Pattern nvarchar(255))
RETURNS BIT
-- dll
AS EXTERNAL NAME RegexFunctions.[RegexFunctions.SQLRegex].MatchRegex
GO
Con esto ya podremos
ejecutar operaciones llamando a la función que hemos creado.
Ya podemos visualizar
la función dentro de las Funciones de nuestra base de datos. Para ejecutarla
podemos hacer clic derecho sobre la función y seleccionamos script comand as.
Y solo debemos agregar
los valores que deseamos para probar nuestra funcion.
SELECT [dbo].[RegExp] (
'skaroque@gmail.com'
,'^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$')
GO
La ejecutamos y
veremos algo como lo siguiente:
Eso será todo por el
momento en el siguiente post vamos a utilizar esta y otras funciones para asegurarnos
de la integridad de los datos de nuestra base de datos.