воскресенье, 15 мая 2011 г.

SQLite + C#

    Недавно произошел мой первый опыт работы с Базами данных (БД). И в этой статье хотел бы рассказать о работе с SQLite в C#.

1. Что нужно знать?

    Во-первых нужно быть знакомым с языком SQL. Могу посоветовать хорошую справку с примерами по SQL - http://www.w3schools.com/sql .
    Во-вторых иметь представление о том что такое БД.


2. Что нам понадобится?

    Использовать мы будем SQLite - легковесная встраиваемая реляционная база данных. Слово «встраиваемый» означает, что SQLite не использует парадигму клиент-сервер, то есть движок SQLite не является отдельно работающим процессом, с которым взаимодействует программа, а предоставляет библиотеку, с которой программа компонуется и движок становится составной частью программы

    Ссылка на SQLite - SQLite-1.0.66.0 (Скачать и установить).


3. Приступаем к работе.

    Предлагаю написать простенькую программу - Телефонный справочник. В нём будут храниться имена людей и ихние номера телефонов.
    С помощью Sqliteman-1.2.1, вы можете легко создать файл БД, и таблицу.
    Структура таблицы:


    Класс Item описывает структуру элемента в таблице:

    Листинг Item.cs:
using System;

namespace TBook
{
    public class Item
    {
        string _name;
        int _phoneNumber;
        int _id;

        public Item(int id, string name, int phoneNumber)
        {
            _id = id;
            _name = name;
            _phoneNumber = phoneNumber;
        }

        public int ID
        {
            get
            {
                return _id;
            }
        }

        public string Name
        {
            get
            {
                return _name;
            }
        }

        public int PhoneNumber
        {
            get
            {
                return _phoneNumber;
            }
        }
    }
}

    Для того чтобы работать с SQLite, добавляем в проект ссылку "System.Data.SQLite". (Проект-> Добавить ссылку). 
    Теперь напишем класс TelephoneBook, в котором реализуем основные методы - Добавление в БД, удаление из БД, очистка таблицы, получение данных из БД.

    Листинг TelephoneBook.cs :
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;

namespace TBook
{
    class TelephoneBook
    {
        const string TABLENAME = "telbook"; // имя моей таблицы

        string _dbConnection;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="path">Path to database file.</param>
        public TelephoneBook(string path)
        {
            _dbConnection = "Data Source=" + path;
        }

        /// <summary>
        /// Method to add item to database
        /// </summary>
        /// <param name="name">Name.</param>
        /// <param name="number">Phone number.</param>
        /// <returns>A boolean true or false to signify success or failure.</returns>
        public bool Add(string name, int number)
        {
            try
            {
                string sqlCommand = "INSERT INTO " + TABLENAME
                    + " (name, number) VALUES (@name, @number)";
                SQLiteConnection cnn = new SQLiteConnection(_dbConnection);
                cnn.Open();
                SQLiteCommand mycommand = new SQLiteCommand(sqlCommand, cnn);
                mycommand.Parameters.Add("@name", DbType.String).Value = name;
                mycommand.Parameters.Add("@number", DbType.Int32).Value = number;
                mycommand.ExecuteNonQuery();
                cnn.Close();
            }
            catch(Exception)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Method to delete item from database
        /// </summary>
        /// <param name="id">ID of item</param>
        /// <returns>A boolean true or false to signify success or failure.</returns>
        public bool Delete(int id)
        {
            try
            {
                string sqlCommand = "delete from " + TABLENAME + " where id=@id";
                SQLiteConnection cnn = new SQLiteConnection(_dbConnection);
                cnn.Open();
                SQLiteCommand mycommand = new SQLiteCommand(sqlCommand, cnn);
                mycommand.Parameters.Add("@id", DbType.Int32).Value = id;
                mycommand.ExecuteNonQuery();
                cnn.Close();
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Method gets table of items by name
        /// </summary>
        /// <param name="name">Name.</param>
        /// <returns></returns>
        public DataTable GetTable(string name)
        {
            DataTable dt = new DataTable();
            try
            {
                string sqlCommand = "SELECT * FROM " + TABLENAME
                    + " WHERE name like @name";
                SQLiteConnection cnn = new SQLiteConnection(_dbConnection);
                cnn.Open();
                SQLiteCommand mycommand = new SQLiteCommand(sqlCommand, cnn);
                mycommand.Parameters.Add("@name", DbType.String).Value = '%' + name + '%';
                SQLiteDataReader reader = mycommand.ExecuteReader();
                dt.Load(reader);
                reader.Close();
                cnn.Close();
            }
            catch (Exception)
            {
                throw new SQLiteException();
            }
            return dt;
        }

        /// <summary>
        /// Method gets items by name
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<Item> GetItemList(string name)
        {
            return ConvertToItemList(GetTable(name).Rows);
        }

        /// <summary>
        /// Method to clear table
        /// </summary>
        public void ClearTable()
        {
            string sqlCommand = "delete from " + TABLENAME;
            SQLiteConnection cnn = new SQLiteConnection(_dbConnection);
            cnn.Open();
            SQLiteCommand mycommand = new SQLiteCommand(sqlCommand, cnn);
            mycommand.ExecuteNonQuery();
            cnn.Close();
        }

        /// <summary>
        /// Method to convert DataRowCollection to List of Item
        /// </summary>
        /// <param name="rows"></param>
        /// <returns></returns>
        private List<Item> ConvertToItemList(DataRowCollection rows)
        {
            List<Item> itemList = new List<Item>();

            for (int i = 0; i < rows.Count; i++)
            {
                itemList.Add(new Item(
                    Convert.ToInt32(rows[i]["id"]),
                    rows[i]["name"].ToString(),
                    Convert.ToInt32(rows[i]["number"])));
            }

            return itemList;
        }
    }
}


   Теперь можно пользоваться классом  TelephoneBook  :
    

TelephoneBook pbook = new TelephoneBook("database");
pbook.Add("Sergey Parakhin", 22321312); // Добавляем запись в БД
pbook.Delete(0); // Удаляем запись с ID равным 0

// Получаем коллекцию всех записей по где встречаеться имя Parakhin:
List<Item> itemList = pbook.GetItemList("Parakhin");
pbook.ClearTable();// Очистка таблицы




    Важно обратить внимание на то как формируется строка  SQL запроса. Во избежания «SQL Injection» атак,  используются параметризованные запросы:
...
string sqlCommand = "INSERT INTO " + TABLENAME
                    + " (name, number) VALUES (@name, @number)";
 ...                

 mycommand.Parameters.Add("@name", DbType.String).Value = name;
 mycommand.Parameters.Add("@number", DbType.Int32).Value = number;

... 

    Собирать строку запроса таким образом не безопасно: 


string sqlCommand = "INSERT INTO " + TABLENAME
        + " (name, number) VALUES (" + name +", " + number + ")";



Я продемонстрировал самый простой пример взаимодействия с БД SQLite на C#.
SQLite очень удобна для прикладных программ с целью хранения данных, т.к. она  не использует парадигму клиент-сервер.  
Так что мы видим, что работать с базами данных совсем несложно, желаю удачи в освоении SQLite, и... да прибудет с вами Сила=)

среда, 15 декабря 2010 г.

Выпадающее меню на CSS



Сегодня расскажу о том как делать красивые меню без использования JavaScript в CSS.
А точнее выпадающее меню. Я рассмотрю самый простой способ. 
Сделаем меню на подобии этого:
Выпадающее меню











Таков будет код HTML:

<ul id="nav">
<li><a href="#null">Главная</a></li>
<li><a href="#null">Контакты</a></li>
<li><a href="#null">Услуги</a>
<ul>
<li><a href="#null">1</a></li>
<li><a href="#null">2</a></li>
<li><a href="#null">3</a></li>
</ul>
</li>
</ul>

А сейчас рассмотрим как из этого с помощью CSS получить простейшее выпадающее меню.
CSS:
#nav, #nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid #000;
  background: #515151;
  float: left;
  width: 100%;
}
#nav li {
  float: left;
  position: relative;
}
#nav li ul {
  display: none;
}
Убрали буллеты из нашего списка — list-style:none. Украсили меню границей и задним фоном.
При помощи float:left выстроили каждый элемент списка <li> в одну линию. Указав display:none скрыли подменю 2-го уровня. Все элементы списка <ul id="nav"> теперь «плавающие».

Свойства float:left мы указали самому контейнеру. Это избавляет нас от так называемого «схлопывания» списка, но заставляет нижележащие элементы обтекать меню справа. Именно поэтому мы указываем ширину для всего меню 100% — чтобы справа просто не оставалось места.
Далее...
#nav a {
  color: #fff;
  text-decoration: none;
  display: block;
  width: 140px;
  padding: 4px 10px;
}
#nav a:hover {
  color: #000;
  background: #ccc;
}
#nav li:hover {
  background: #333;
}
Сначало мы оформили ссылки (#nav a), чтобы они так сказать были похожи на кнопки.
Каждому элементу <a> мы присвоили свойство display:block, что дало нашим ссылкам ширину и высоту. 
text-decoration:none - убирает подчеркивание (ведь ссылка содержит подчеркивание)
Задали ширину каждой ссылки 140 пикселей (не включая отступы).
Селектор #nav a:hover срабатывает в том случае, когда мы подводим курсор к ссылке,а 
#nav li:hover — когда подводим его к элементу списка.

Сейчас все выглядит как простое меню, следующим шагом мы сделаем как и задуманно его выпадающим.
Мы дописываем к уже существующему правилу:
#nav li ul 
следующие инструкции:
#nav li ul {
  display: none;
  position: absolute;
  background: #333;
  padding: 8px 0;
  width: 158px;
}

position:absolute служит для абсолютного позиционирования подменю относительно элемента <li> верхнего уровня.
#nav li li a {
  width: 138px;
}
#nav li:hover ul {
  display: block;
}
Именно строка display:block для #nav li:hover ul заставляет подменю появиться при подводе курсора к ссылке, сменяя ранее установленный режим (display:none).

Мы создали простейшее выпадающее меню, так же можно добавить 3 уровень меню, фон сделать спрайтами, и таким образом можно создать весьма симпатичное меню:)

воскресенье, 14 ноября 2010 г.

Как оптимизировать загрузку изображений для кнопок (CSS)


В CSS мы можем применить псевдо-класс :hover к ссылке и добавить свойства, которые будут задействованы при наведении указателя на ссылку.

a:link, a:visited {
    width: 160px;
    height: 30px;
    display: block;
    overflow: hidden;
    background: url(images/nav1.gif) 0px 0px no-repeat;
}
a:hover, a:active {
    background-position: 0px -30px;
}

Изображение nav1.gif содержит в себе сразу два состояния кнопки, а при наведении меняется положение фона:

Оригинал: How to make Buttons with Hover Load Faster

Надо заметить что эту технику можно применять не только к кнопкам, но и к другим элементам. Например на известном видеохостинге Youtube в одном изображении объединены сразу несколько графических элементов:

среда, 29 сентября 2010 г.

Java 4-Ever Trailer

Сегодня посмотрел оч позитивный клип на youtube.com
Особенно понравится Java-кодерам=)

Пару интерестных мелких задачек по C++


В этом посте хочу расмотреть пару интерестных мелких задач по C++ "для тренировки и лучшего понимания"=)
1)Даны две переменных:
int a = 10;
int b = 25;
поменять значения местами без использование дополнительных переменных.

Задачку можно решить арифметически и с помощью битовых операций:
Арифметически:
a=a+b;
b=a-b;
a=a-b;
Используем битовые операции:
a ^= b ^= a ^= b; 

2) Напишите программу умножения двух чисел ЛЮБЫМ способом. условие только одно - НИГДЕ не использовать оператор *
Так же можно решить арифметически:
double b=8;
double c=2.5;
double a=b/(1/c);

3) Найти большее из 2-х чисел, при этом не использовать if, циклов, вспомогательны переменных, различных функций и т.д.
int a, b, c;
c=(a>b)*a+(b>a)*b;
Я думаю понятно как работает=) если выражение в скобках истенное, то скобка возвращает 1, иначе - 0.

4) B вот еще одна коварная задачка =)
int main()
{
    http: //www.google.com/
    return 0;
}
есть ли в данном коде ошибка(компилятором естественно не пользоваться )) )? Если есть, то какая и как исправить, а если нет, то почему?
Ответ таков:
Перед "www" начинается область комментария, то есть дальнейшая область не учитывается.
А вот "http:" рассматривается как обычная метка. Так что ошибки нет!=)