25 oktober, 2011

Utveckling: Notepad++ Länka till CHM PHP Manual

Här är ett tips, som jag fann precis nu, för er PHP-utvecklare som vill integrera PHP manualen in i välkända Notepad++.

Skapa ett nytt kommando i Notepad++ (engelsk version) på följande sätt:
  1. Tryck på knappen F5 för att öppna fönstret "Run"
  2. Klistra in följande text i rutan:

    hh.exe mk:@MSITStore:C:\manuals\php_enhanced_en.chm::/res/function.$(CURRENT_WORD).html

  3. Tryck på knappen "Save..." och välj vilka tangenter som skall aktivera genvägen. Jag valde t.ex CTRL+ALT+F10
  4. Det som händer är att jag kan markera en PHP funktion i koden jag redigerar för tillfället och kan då öppna den lokala PHP manualen genom att aktivera genvägen med tangentbordet.



Tips!
Detta kommando fungerar även på andra CHM-dokument för att skapa genvägar, men du måste ändra sökvägen.

20 oktober, 2011

Windows XP: Symboliska länkar / Symbolic links

Åh, jag fann precis ett underbart program till Windows XP som fungerar för er som har NTFS och som vill skapa symboliska länkar.

Det heter Junction, är utvecklad av Microsoft, och kan skapa en symbolisk länk (symbolic linc) [1]

När vill man använda detta? Jag använder det t.ex när jag vill säkerhetskopiera min iPad till en annan plats än den förkonfigurerade sökvägen inuti iTunes, vilket inte går att redigera.

iTunes vill spara alla säkerhetskopieringar till följande sökväg:
C:\Documents and Settings\\Application Data\Apple Computer\MobileSync\Backup

Men jag vill spara filerna här istället:
G:\ipad_backup

Då kan jag köra följande kommando i Windows XP:
C:\junction\> junction.exe "C:\Documents and Settings\\Application Data\Apple Computer\MobileSync\Backup" G:\ipad_backup -s

Nu fungerar det så att om iTunes kopierar filer till katalogen "Backup" så skickas de istället till katalogen "ipad_backup". Bra va!

I Windows Vista och Windows 7 finns det inbyggda kommandon för detta men jag har ännu inte provat själv.

Referenser
[1] http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx

04 oktober, 2011

Tutorial/Network: How to subnet a Class A IP Address (VLSM/CIDR)

Introduction
Hi everyone!
I am going to go through how to subnet a class A IP address network for CIDR. This is not going to be a tutorial for complete beginners but instead towards network technicians that are either studying or work with IT Networks and Communication.

Usually I write articles in Swedish but I thought that this would fit best in english because I think that more english-speaking people are trying to find solutions on this topic. This article is also written in memory for myself so I don't have to search through so many websites when I have this problem in the future.


The goal with this tutorial
Take one IP address network and create more smaller networks from that. This is good when we for example want to summarize addresses.

Take this IP network address: 28.32.0.0/11
We want 4 networks with prefix /14
and the results will be something like this:

Address. Prefix Subnetmask....... Range............Broadcast
28.32.0.0 /14 255.252.0.0 28.32.0.1 - 28.35.255.254 28.35.255.255
28.36.0.0 /14 255.252.0.0 28.36.0.1 - 28.39.255.254 28.39.255.255
28.40.0.0 /14 255.252.0.0 28.40.0.1 - 28.43.255.254 28.43.255.255
28.44.0.0 /14 255.252.0.0 28.44.0.1 - 28.47.255.254 28.47.255.255

Note:
Please not that this is not optimized for real networks. This is just an example and you have to adapt it to your situation and planning. But I think you can make it work.


Let's start
We have IP network address 28.32.0.0/11 and we want to create several subnetworks with prefix /14.

Let's calculate the subnetmask and binary for prefix 11 and 14:
Prefix /11: 255.224.0.0 => 11111111.11100000.00000000.00000000 (eleven 1s)
Prefix /14: 255.252.0.0 => 11111111.11111100. 00000000.00000000 (fourteen 1s)

The fourteen bits are the network bits and they are marked with red
The three bits marked with orange color are subnet bits.
The zeroes are host bits and they are marked with blue color.

Total number of hosts
To calculate the total number of hosts for each subnet we need to cound how many zeroes we have: 2 + 8 + 8 = 18

Then we can use a formula for the total number and the usable total number of hosts IP addresses.

Total number of hosts: 2^18 = 262144
Usable total number of hosts: 2^18 - 2 = 262142

Note:
We subtract two because we remove the network address and broadcast address for the assignable range of host IP addresses.


Calculate the subnet IP ranges
First we search for our increment, a value that helps us to verify the calculation later on. You find the increment by looking at the right most binary 1 in the subnetmask. Then you convert that binary 1 to its decimal equivalent.

Example
28.32 = 00011100.00100000
255.252 = 11111111.11111100

00000100 = 4

The increment is marked with green color. The increment is used to easier check that the ranges are correct. Every new subnet has incremented the octet by 4 when we calculate the range.

Remember this rule: We only change the zeroes and the subnet bits when calculating the ranges.

We start with subnet zero and I only show the second octet (28.32.0.0) because it's most important. The bits are marked with their respective colors to make it easier for you to follow. I only show the network address and the broadcast address for each subnet. The usable host IP addresses are contained within.

Subnet bits are orange
Host bits are blue
Network bits are red

Can you see the pattern? Please note that the network and broadcast addresses are incremented by 4 for each new subnet. 36-32 = 4
#0 00100000 - 00100011 (32-35)
#1 00100100 - 00100111 (36-39)
#2 00101000 - 00101011 (40-43) <-- See example below
#3 00101100 - 00101111 (44-47)
#4 00110000 - 00110011 (48-51)
... etc ...
Here is an example of subnet #2:

Network..First IP....Last IP.......Broadcast
28.40.0.0 28.40.0.1 - 28.43.255.254 28.43.255.255

Decimal.........Binary
28.40.0.0.... = 00011100.00101000.00000000.00000000
28.40.0.1.... = 00011100.00101000.00000000.00000001
28.43.255.254 = 00011100.00101011.11111111.11111110
28.43.255.255 = 00011100.00101011.11111111.11111111
And now we're done! At least we now have a table with numbers that we can expand further and assist us in our network design and planning phase.


Extra assignment ahead
Try to come up with an IP address that summarizes subnets #1 to #3?

Summarization is used mostly in routers to reduce the size if the routing tables and to reduce flapping routes; routes that changes, get added or get removed. If you summarize these routes, they will not be noticed futher down. This is especially useful in OSPF networks between areas to reduce memory and CPU processing. The core routers have summarized routes to surrounding areas.


Read here if you want the solution
28.36.0.0/12

How did I come up with that? First I compared subnet #1, #2 and #3 to see what bits that were in common. The first four bits (0010) in the second octet were the same in all three subnets.

Then I calculate the new subnetmask prefix value for that octect, which is obviously 4, and then adding 8 from the first octet. 8+4 = 12. That's because I only want to use the subnetmask that includes these four bits that were same.

At last I just take the value of the octet from subnet number #1 and we have the final IP network address.

Have a nice day!

02 mars, 2011

MySQL: InnoDB Foreign keys och Cascade

Förord
Hej på er! Nu ska jag förklara lite mer om databasen MySQL och en av databasmotorerna InnoDB. Jag upptäckte igår vad detta innebär och då började jag komma ihåg att jag hade läst om detta förut i en bra bok om just MySQL databashantering. Boken heter "MySQL handboken : [den snabba vägen till grunderna i MySQL]" och passar utmärkt till den som vill lära sig MySQL och gå in lite mer på djupet.

När jag läste boken förstod jag inte så mycket om foreign keys, som på svenska heter "främmande nycklar", men det förstår jag bättre nu. Därför har jag tänkt att visa ett exempel på när det kan vara mycket användbart.

Mycket bra läsning på engelska finns i en artikel publicerad på InnoDB.com [2]

Introduktion
Vad är MySQL?
Okej, som de flesta vet så är MySQL en typ av databas där man kan lagra information på ett strukturerat sätt. Och för er som inte vet, så vet ni nu vad MySQL är för något.,

SQL = Structured Query Language

Men vad kan MySQL användas till?
MySQL använder s.k. SQL-frågor för att skicka och hämta data från en databas. MySQL kan användas till att lagra information strukturerat om t.ex kunder som har bokat klipptider hos en frisör, eller produkter och artiklar som man vill sälja via en hemsida. När någon sedan har lagt en beställning kan man koppla produkterna till en specifik beställning som i sin tur hör till en registrerad kund.

Ett vanligt exempel från gymnasiet är en databas med elever som kommer att börja på skolan nästkommande termin. Vi fick lära oss hur man designar en databas med tabeller som är relaterade till varandra och hur man endast kan tillåta unika personer i databasen baserat på unika personnummer.

Fint, men vad är InnoDB för något?
I MySQL används olika databasmotorer (engines) för att spara och hämta data på olika sätt. Ska datans integritet kontrolleras eller spelar det ingen roll? Ska tabeller relateras med varandra eller skötas med programmering? Det är uppgiften som en databasmotor har.

InnoDB är inte så vanlig bland nybörjare eftersom standardmotorn heter MyISAM och många vet inte eller bryr sig inte om att kontrollera vilken databasmotor man använder. Databasen funkar ju fortfarande på samma sätt, eller? Ja det är sant men InnoDB kan kontrollera data i databasens tabeller så att länkarna, relationerna och integriteten inte bryts om en ändring sker i databasen.

Huvudregeln säger att i en relationsdatabas (en databas med relationer vilket hörs på namnet) så måste relaterade nycklar ha en korrekt länkning - nyckel1 med ID 4 i tabell A måste vara samma som nyckel1 med ID 4 i tabell B. Med InnoDB kan man kontrollera att ID-numret måste vara samma i båda tabellerna som är relaterade med varandra genom användning av främmande nycklar.

Om du inte förstår så är det helt förståeligt. Det kan vara ett svårt koncept i början innan man lär sig. Jag kommer strax gå igenom skillnaderna mellan InnoDB och MyISAM (den vanligaste databasmotorn).


Först en kort beskrivning om primärnycklar och främmande nycklar
En primärnyckel måste vara unik i en tabell. Dubbletter och kopior får inte förekomma. Ett vanligt exempel på en primärnyckel är ett ID i en tabell som automatiskt räknar uppåt när nya rader med data läggs till. Om man ska ha ett personnummer i en databas så passar personnumret utmärkt som en primärnyckel eftersom det ska vara unikt. Detta är bra så att man inte råkar fylla i ett som redan finns.


När ska man använda InnoDB och MyISAM?
Kortfattat
Om du har en t.ex en hemsida med en databas som innehåller en tabell som kommer att uppdateras och ändras kontinuerligt och väldigt ofta, då passar InnoDB. Speciellt om du har flera tabeller som är relaterade till varandra. Då kan InnoDB säga till när det blir fel och hjälpa till med uppdatering i andra tabeller. InnoDB är långsammare när det gäller SELECT och ändringar.

MyISAM ska man helst använda om det sällan sker INSERT, UPDATE och DELETE i tabellerna. Alltså om det sker mycket SELECT. MyISAM är snabbast men är också enklast att arbeta med.


Det bästa scenariot är...
Om man kan köra två databaser som master och slave med replikering. Då kan en av dem innehålla tabeller med InnoDB som håller koll på all integritet, och den andra har kopior av alla tabeller från den första fast med MyISAM istället för InnoDB. När data ska hämtas så anropas den andra med MyISAM. När data ska läggas till, uppdateras eller tas bort så anropas den första. Då får man det bästa av två världar - nja två olika tekniker i alla fall.


Nu ett exempel med InnoDB

Exempel 1
Beskrivning: Vi kommer ha en tabell där vi lagrar information om kategorier för produkter som säljs på en hemsida. Observera att detta exempel inte kommer fungera med MyISAM.

Skapa först en databas. Skapa sedan nedanstående tabeller.

CREATE TABLE tbl_products(
product_id INT UNSIGNED NOT NULL,
product_name VARCHAR(20),
PRIMARY KEY(product_id)
) ENGINE=InnoDB;
Detta är tabellen med produkter som sedan ska kopplas till kategorier.


CREATE TABLE tbl_categories(
category_id INT UNSIGNED NOT NULL,
category_name VARCHAR(20),
PRIMARY KEY(category_id)
) ENGINE=InnoDB;
Detta är tabellen med kategorier. Tabellerna ovanför beskriver inte hur de är relaterade med varandra. För det behöver vi ännu en tabell.

CREATE TABLE tbl_categories_products(
category_id INT UNSIGNED NOT NULL,
product_id INT UNSIGNED NOT NULL,
PRIMARY KEY(product_id, category_id),
FOREIGN KEY (category_id) REFERENCES tbl_categories(category_id),
FOREIGN KEY (product_id) REFERENCES tbl_products(product_id)
) ENGINE=InnoDB;


Nu kan vi se på bilden här nedanför hur relationen mellan tabellerna ser ut.

(Bild 1) Relation mellan tabeller produkter och kategorier

Lägga till lite data till tabellerna. Här lägger vi till några produkter:
INSERT INTO tbl_products(product_id, product_name)
VALUES
(1, 'MP3 spelare'),
(2, 'iPod'),
(3, 'iPad'),
(4, 'Dell Dimension 1111 PC'),
(5, 'PHP och MySQL Handboken'),
(6, 'Bäverdalen'),
(7, 'Samsung Galaxy Tab')


Lägg till några kategorier för produkterna:
INSERT INTO tbl_categories(category_id, category_name)
VALUES
(1, 'Musikspelare'),
(2, 'Läsplattor'),
(3, 'PC'),
(4, 'Böcker')


Skapa relationer mellan kategorier och produkter:
INSERT INTO tbl_categories_products(category_id, product_id)
VALUES
(1, 1),
(1, 2),
(2, 3),
(3, 4),
(4, 5),
(4, 6),
(2, 7)


Försök att lista ut själv hur relationen är uppbyggd. Första kolumnen är vilken kategori som den andra kolumnen tillhör. T.ex "PHP och MySQL Handboken" tillhör kategori nr 4 vilket är "Böcker".

Resultat
Nu måste utvecklaren och alla mjukvaror som tänker använda tabellerna tänka på att kontrollera integriteten själva genom att uppdatera alla tabeller som ändras för varje SQL-fråga till databasen. ID numren måste stämma överens annars får man ett felmeddelande av databasen. Så om jag nu skulle råka fylla i data (en post) i tabellen tbl_categories_products med följande SQL-fråga, så skulle jag få ett felmeddelande eftersom kategori ID-numret inte finns i tabellen tbl_categories.

INSERT INTO tbl_categories_products(category_id, product_id) VALUES (8, 2)



Exempel för MyISAM
Tyvärr har jag inte några exempel för tabeller som har MyISAM men jag vet att det fungerar genom att skapa sk Triggers. Läs gärna referensen [1] för att läsa mer.


Vad händer om man vill ändra ett ID-nummer i tabellen för kategorier?
Då blir det fel. Man måste ändra i båda tabellerna samtidigt har jag för mig. Men det problemet kan vi lösa i kommande text och exempel.


Cascade för "delete" och "update"
Med nyckelordet "Cascade" kan man tillåta att InnoDB själv ska ha kontroll över alla tabellerna automatiskt. Säg nu att jag vill byta ut ID-numret för kategorin "Läsplattor" till ID 17, då kan jag uppdatera numret för category_id i tabellen tbl_categories och ändringen sker även automatiskt i tabellen tbl_categories_products eftersom den är relaterad till category_id och måste vara likadan. Ändras en tabell så måste den andra tabellen också ändras.

Detsamma gäller när en rad tas bort. Om jag känner för att ta bort hela kategorin "Böcker" (ID nr 4) så kommer raden/raderna i tabellen tbl_categories_products med category_id = 4 att också tas bort.

Hur gör man då detta... man kan använda Cascade när man skapar en främmande nyckel. Nu kommer jag visa med ett exempel hur man gör. Man kan använda CREATE TABLE och ALTER TABLE för att ändra i efterhand. Jag kommer visa hur man gör via CREATE TABLE.

CREATE TABLE tbl_categories_products(
category_id INT UNSIGNED NOT NULL,
product_id INT UNSIGNED NOT NULL,
PRIMARY KEY(product_id, category_id),
FOREIGN KEY (category_id) REFERENCES tbl_categories(category_id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES tbl_products(product_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB;


Detta betyder nu att tabellen övervakar de främmande nycklarna i de främmande tabellerna tbl_categories och tbl_products.

Om du nu testar att köra följande SQL-fråga så kan du se att två tabeller uppdateras. Den ena som du valde och den andra som har en relation med den du valde.

UPDATE tbl_categories SET category_id = 14 WHERE category_id = 2

Kontrollera tabellerna

SELECT * FROM tbl_categories
SELECT * FROM tbl_products
SELECT * FROM tbl_categories_products (har ändrat sitt category_id som var 2 automatiskt till 14)

Det borde se ut ungefär så här nu i tabellen tbl_categories:
+-------------+---------------+
| category_id | category_name |
+-------------+---------------+
| 1 | Musikspelare |
+-------------+---------------+
| 14 | Läsplattor |
+-------------+---------------+
| 3 | PC |
+-------------+---------------+
| 4 | Böcker |
+-------------+---------------+

tbl_categories_products:
+-------------+------------+
| category_id | product_id |
+-------------+------------+
| 1 | 1 |
+-------------+------------+
| 1 | 2 |
+-------------+------------+
| 14 | 3 |
+-------------+------------+
| 3 | 4 |
+-------------+------------+
| 4 | 5 |
+-------------+------------+
| 4 | 6 |
+-------------+------------+
| 14 | 7 |
+-------------+------------+


Slutsats
Slutsatsen med detta testet är att jag nu kommer överväga att använda InnoDB för mer kritiska applikationer där det sker många ändringar i databasen. Om jag kör detta system på en hemsida kommer jag att köra cachelagring av all data så behöver data bara hämtas en gång med SELECT från databasen och resten sparas i textfiler.

Det kommer också bli svårare att designa sin databas så jag får planera bättre i framtiden exakt vilka tabeller jag vill använda och hur man eventuellt kan uppdatera databasen i framtiden för att minska problem och fel så mycket som möjligt.

Nu behöver jag bara uppdatera en tabell och behöver inte tänka på vilka andra tabeller som är indirekt relaterade till tabellen genom "osynliga" relationer. Med detta menar jag att jag alltid innan har skrivit applikationer som själva måste hålla reda på att ändra i t.ex tabellen tbl_categories_products så fort jag uppdaterar ett kategori ID eller tar bort en kategori.

Ett bra scenario är kommentarer som är kopplade till ett blogginlägg. Tar man bort blogginlägget så ska alla tillhörande kommentarer tas bort automatiskt utan att jag som programmerare behöver tänkta på att skriva kod som måste utföra det manuellt. Nu sköts allt i databasen och koden blir mer abstract och enklare att underhålla.

Slutord
Det var allt för den här gången. Jag hoppas att artikeln har varit till någon nytta för er.

Mvh
Waschman


Referenser
[1] http://dev.mysql.com/tech-resources/articles/mysql-enforcing-foreign-keys.html
[2] http://blogs.innodb.com/wp/2010/09/mysql-5-5-innodb-as-default-storage-engine/

10 februari, 2011

jQuery: Ny version 1.5 av jQuery men bug om man använder jQuery UI 1.8.9

jQuery version 1.5 släpptes för några dagar sedan men redan har jag hittat ett fel, vilket är ganska allvarligt. Versionen blockerar kod som använder sortable och draggable i paketet jQuery UI om de är anslutna till varandra (connectedWith)

Ni kan läsa mer på detta foruminlägg: http://forum.jquery.com/topic/weird-weird-error-on-draggable

Följande kod kommer alltså inte att fungera i nuläget om ni använder version 1.5:
$('.cms-block-container').addClass('cms-sortable');
$('.cms-sortable').sortable({
appendTo: 'body',
connectWith: '.cms-sortable',
revert: true,
placeholder: 'sortable-placeholder',
delay: 300,
opacity: 0.75,
handle: '.cms-block-move-handle',
cancel: '.cms-drop-zone-placeholder',
helper: function(event) {
return $('sortable-html-code-here');
},
... and activate, deactivate etc.


$('.cms-draggable').draggable({
appendTo: 'body',
connectToSortable: '.cms-block-container',
helper: 'clone',
cursor: 'move',
opacity: 0.75,
cursorAt: { left: -3, top: -3},
helper: function(event) {
return $('sortable-html-code-here');
}
}).disableSelection();

Lösningen på problemet är att använda en tidigare version, v.1.4.4 är bekräftad och fungerar.

Detta är varför jag inte använder skript som heter latest.js när man infogar kod från exempelvis googlecode.

Välkomna till bloggen

Välkomna ska ni vara kära besökare. Jag skriver om IT för att det är kul och för att jag vill dela med mig av information och kunskap. Jag försöker hålla bloggen så kategoriserad som möjligt för att ni enklare ska hitta intressanta länkar och artiklar.