pondělí 12. října 2015

MS SQL vs. MySQL



Sloupec v MySQL který povoluje ukládat jen hodnoty z výčtu

[mycol] set('1','2','3','4','5','6') default NULL,


Alternativní zápis pro MS SQL který umožňuje také pouze hodnoty z výčtu

Create table [enum_tbl] (
[enum_nr] tinyint NOT NULL CHECK (enum_nr IN('1','2','3','4','5','6','7','8','9','10'))
)

Create table [enum_tbl2] (
[enum_nr] tinyint NULL CHECK (enum_nr IN('1','2','3','4','5','6','7','8','9','10'))
)


Problém při přepisu aplikace z MySQL na MS SQL je v tom že pokud používáte UTF-8
tak každá stringová hodnota pro MS SQL musí obsahovat prefix N'hodnota'.
Čimž se trochu komplikuje vytváření SQL příkazů.


REPLACE

'collate utf8_bin'  => ''
'int(11)' => 'int'
'varchar' => 'nvarchar'
'unsigned' =>''
'auto_increment' => 'IDENTITY(1,1)'

PHP 
'<?' => '<?php'
sqlsrv_query($objConn, $strQueryIN, $params)

NumRows
$options =  array( "Scrollable" => SQLSRV_CURSOR_KEYSET );
$stmt = sqlsrv_query( $objConn, $strQueryIN, $params, $options);

Dotaz je potřeba volat s Options = Scrolable, aby bylo možné použít sql_num_rows

mysql_num_rows($result) =>

 if( sqlsrv_fetch( $result ) === false) {
     die( print_r( sqlsrv_errors(), true));
  }
    $REcount = sqlsrv_num_rows($result) !== false
? sqlsrv_get_field($result, 0)
: 0;


FetchArray
mysql_fetch_assoc($result) => sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)

Result
mysql_result($result, 0) => sqlsrv_get_field($result, 0)

if(sqlsrv_num_rows($result)===false) {

if ($REcount!==false)


Last Insert ID
mysql_insert_id() => mssql_insert_id()

 function mssql_insert_id() {
    $id = 0;
    $res = MSSQLQuery($conn, "SELECT @@identity AS id");
    if ($row = mssql_fetch_array($res, MSSQL_ASSOC)) {
        $id = $row["id"];
    }
    return $id;
  }


mysql_real_escape_string

function mssql_escape($str)
{
    if(get_magic_quotes_gpc())
    {
        $str= stripslashes($str);
    }
    return str_replace("'", "''", $str);
}

Zdroje:
http://php.net/manual/en/intro.mssql.php
http://stackoverflow.com/questions/1434298/sql-server-equivalent-to-mysql-enum-data-type
http://dev.mysql.com/doc/refman/5.0/en/set.html
http://stackoverflow.com/questions/12880567/equivalent-of-mysql-insert-id-for-ms-sql-server
http://stackoverflow.com/questions/2146546/mysql-real-escape-string-alternative-for-sql-server
http://php.net/manual/en/function.sqlsrv-fetch-array.php
http://php.net/manual/en/function.sqlsrv-num-rows.php
http://php.net/manual/en/function.sqlsrv-get-field.php


čtvrtek 8. října 2015

Repository TestCase

Testovací scénáře pro Repository
Repository má klasicky 4 operace - vytvoření, načtení, upravení a smazání. Každou z nich ale musíme otestovat na minimálně dvě krajní situace abychom si ověřili chování v těchto případech. Úspěšné vrácení záznamu po jeho načtení z DB nebo selhání a vyhození vyjímky při pokusu smazat záznam, který je zamčený, nebo na něj uživatel nemá práva.

Každé vytvoření, nebo úprava záznamu má ale určité pravidla pro validaci záznamu, které je možné do databáze uložit. Například délky textových řetězců, povinnost vyplnit některý údaj (not null), formát datumu, číselné datové typy, atp. To nám počet scénářů navyšuje.

Výhodou ale může být použití DataDriven Testů, kdy se jednomu testu předává více testovacíh hodnot. Tímto můžeme pokrýt jedním testem velké množství scénářů testování krajích hodnot.

Kupříkladu entita  musí mít vyplně:
  • datum vytvoření
  • id uživatele který ji založil
  • potom typ záznamu musí být jedna ze dvou variant
  • a pokud odpovídá variantě 1 tak musí být vyplněna ještě poznámka
Create - Vytvoření záznamu
  • Záznam se podaří vytvořit
  • Záznam se vytvořit nepodařilo
Find - nalezne záznam podle primárního klíče
  • Záznam se podaří nalézt
  • Záznam se nalézt nepodařilo
GetAll - Získá z databáze všechny záznamy
  • V kolekci není žádný záznam
  • Podařilo se získat alespoň jeden záznam
  • Načítání se nezdařilo např. Chyba spojení s DB
Search - Získá z databáze všechny zázanamy které vyhovují podmínce
  • Nebylo nic nalezeno
  • Nalezne alespoň jeden záznam
  • Vyhledávání selhalo
Update - akualizace záznamu
  • Update záznamu se povede
  • Update se nepovede
Delete - smazání záznamu
  • Delete se povede 
  • Delete se nepovede (např. záznam byl již smazán, uživatel nemá práva k záznamu)
Pokud vezmeme 20 testovacích scénářů a budeme počítat 30 minut na implementaci jednoho dostáváme se na čas 10 hodin na implementaci testů. Jak dlouho by trvalo vašemu testerovi tuto funkčnost otestovat v hotové aplikaci?

Přenos dat z XFS do NTFS

Před několika lety jsem si koupil NAS od ZYXELu. Funguje v pořádku už několik let. Při experimentech jsem ale několikrát navodil situaci kdy jsem se nebyl schopný k souborům na disku dostat. Naštěstí existuje aplikace kterou se na disk dostanete i z Windows. http://www.ufsexplorer.com/download.php Je možné ji vyzkoušet bezplatně ale kopírovat můžete pouze soubory do velikosti myslím že pouze 500 kB. Což nestačí ani na záchranu fotek. Takže jsem si musel koupit licenci. Kdyby tedy někdo chtěl stahnout data z jeho XFS disku tak se klidně ozvěte :)

Povolení FileStream na MS SQL

Je potřeba zapsat tento script a spustit ho

EXEC sp_configure filestream_access_level, 2

RECONFIGURE
Nastavení pomocí SQL Server Configuration Manager_u nezabralo ani po restartu serveru

čtvrtek 24. září 2015

CodeReview - není k ničemu

Když dělají dva totéž, nikdy to není totéž.
Překvapivě i když jste to vy sami jen o nějaký den, týde či měsíc starší.

Tím se ukazuje důležitost toho, aby po Vás váš kód někdo prošel, zaťukal si na čelo a řek "Můžeš mi prosím tě vysvětlit rozdíl mezi těmito dvěma propertama?" Pokud nemáte kolegu, který by to pro Vás udělal, tak hold před každým commitem musíte otevřít každý upravený soubor a podívat se co jste změnili a jestli o řádek vedle není metoda, kterou by jste mohli refaktorovat.


public bool IsPossibleToLogin
{
 get
 {
  return this.BaseAddress != null
  && !string.IsNullOrEmpty(this.BaseAddress.ToString())
  && !string.IsNullOrEmpty(this.UserName) 
  && !string.IsNullOrEmpty(this.Password);
 }
}

public bool IsSetLogin
{
 get
 {
  return !string.IsNullOrEmpty(this.UserName)
  && !string.IsNullOrEmpty(this.Password)
  && !string.IsNullOrEmpty(this.BaseAddress.ToString());
 }
}


První krok refaktoringu
Nahradit výpočet v druhé proprty výpočtem v první, protože je robustnější a kontroluje i jestli je vyplněna adresa. Označení property jako Obsolet dáte kolegů nebo partnerům kteří vaši knihovnu používají najevo, že plánujete tuto property odstranit, čím ji mají nahradit a kdy ji odstaníte.

public bool IsPossibleToLogin
{
 get
 {
  return this.BaseAddress != null
  && !string.IsNullOrEmpty(this.BaseAddress.ToString())
  && !string.IsNullOrEmpty(this.UserName) 
  && !string.IsNullOrEmpty(this.Password);
 }
}

[Obsolete("Duplicitní property. Použíjte property IsPossibleToLogin. Ve verzi 1.4.5 bude odstraněna.")]
public bool IsSetLogin
{
 get
 {
  return this.IsPossibleToLogin;
 }
}

Druhý krok refaktoringu
Odstraníme reference na obsolet propertu, které se nám po buildu zobrazí v [Error listu].

Třetí krok refaktoringu
Odstraníme obsoleteproperty.

středa 16. září 2015

Ftp vs. WebDeploy

Způsobů jak dostat hotový projekt na produkční server je několi. V tomto blogpostu porovnám jaký je rozdíl mezí FTP a WebDeployem.

FTP
Pro konfiguraci tohoto způsobu potřebujete:

  • Adresu ftp serveru
  • Uživatelské jméno
  • Heslo
  • Cestu k webRoot adresáři
  • URL adresu nasazeného projektu pro otevření prohlížeče po nasazení

Jakmile toto vše zadáte do průvodce Publish profilu, máte ještě možnost nastavit že se všechny soubory mají nejdříve smazat a potom zkopírovat nové verze. To Vám o něco prodlouří dobu nasazení, protože mazání spousty malých souborů je jen o něco rychlejší než jejich nahrání zpšt na server.

WebDeploy 
Pro konfiguraci webDeploye potřebujeme podobné údaje s tím rozdílem, že namísto webroot adresáře potřebujeme znát site name což je název stránky v IIS
Z buildovaný projekt je pak zabalen do ZIP balíčku s manifestem ve kterém je uvedeno jak se má balíček nasadit na IIS. Pomocí služby WebDeploy kterou jenutné na IIS nainstalovat se balíček nakopíruje na server kde se rozbalí do požadovaného adresáře. Což je asi "trilionkrát" rychlejší než používání mazání a kopírování přes FTP.

úterý 8. září 2015

Deploy na IIS 6.1 MVC 5 .NET4.0

Do souboru Web.Config je potřeba přidat:
<modules runAllManagedModulesForAllRequests="true">

Po dvou hodinách googlení a nastavování se to rozjelo

Klíčový řádek je:
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis -ir

Pak je ještě potřeba nastavit v MimeType příponu pro *.svg
image/svg+xml


<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" xdt:Transform="SetAttributes"/>
    <staticContent>
      <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
    </staticContent>
  </system.webServer> 

Zdroj:
http://stackoverflow.com/questions/21623654/issue-deploying-asp-net-mvc-5-to-iis-server