Юзабилити

18 сент. 2009 г. | | |


— У вас это… юзабилити плохое.
— Мне надо, чтобы было просто и удобно.
— Я не моряк, чтобы разбираться, как его крутить.
— Мне жаль вас, у вас всё так сложно и неудобно.
Взято с http://malinnikov.ru

Альтернатива массивам для извращенцев

| | |

Как-то раз попросил знакомый решить такую вот задачку (цитирую):

смотри есть к примеру ряд переменных
перем1
перем2
перем3
можно ли как то обратиться
к ним в цикле например
Для сч = 1 по 3 Цикл
сообщить(Перем+Сч)
КонецЦикла

Первое, и адекватное, что приходит в голову - использовать массив. Но по условиям задачи, массив никак не подходил. Но вспомнилось, что-то где-то виделось... и вот, реализация данной задачи на php.

<?
for($i = 0; $i<10; $i++)
{
$commonVar = "varName".$i;
$$commonVar = "new value".$i; /*в этом месте переменной с именем выражения "varName".$i присваивается значение "new value*/
echo $$commonVar."<br />";
}
?>

15 сент. 2009 г. | | |


25 августа сего года компания DevExpress выпустила совершенно free очень полезную надстройку для Visual Studio 8 CodeRushExpress for C# and VB, скачать который можно тут.
CodeRushExpress предлагает расширенный набор функций для выделения кода, навигации в коде и объявлений классов и тд в коде.
Кроме того, CodeRush Xpress включает в себя более 50 рефакторингов, что, конечно же, просто замечательно. Если вы не счастливый обладатель полной версии CodeRush, то определенно must have в арсенале разработчика!

Разработчики всех стран, объединяйтесь!

13 сент. 2009 г. | | |

Замечательная тема, посвещенная Дню Программиста http://www.techdays.ru/DevDay/
Разработчики всех стран, объединяйтесь!

Законы программирования

12 сент. 2009 г. | | |

Закон программирования № 1. Ничто не работает так, как планировалось запрограммировать.

Закон программирования № 2. Ничто не программируется так, как должно работать.

Закон программирования № 3. Хороший программист характеризуется умением доказать почему задачу невозможно выполнить, когда ему просто лень её выполнять.

Закон программирования № 4. На решение проблемы уходит в три раза меньше времени, чем на обсуждение всех "за" и "против" её решения.

Закон программирования № 5. Обещанный срок сдачи - это аккуратно рассчитанная дата окончания проекта плюс шесть месяцев.

Закон программирования № 6. Программисту всегда известна последовательность действий, которыми пользователь может повесить его программу, но он никогда не чинит эту проблему, надеясь на то, что никому никогда не придёт в голову эту последовательность исполнять.

Закон программирования № 7. Настоящие программисты любят Windоws - все ошибки, сделанные по собственной тупости, можно свалить на Micrоsоft.

Закон программирования № 9. В случае голодовки настоящий программист ещё месяц сможет питаться едой, выковырянной из-под кнопок клавиатуры.

Закон программирования № 10. Настоящий программист уже как минимум поменял три залитых пивом клавиатуры.

Закон программирования № 11. Все, кто испытывает проблемы с настройкой кодировки, автоматически считаются неандертальцами.

Закон программирования № 12. Дилетантские разговоры о компьютерах вызывают резкую тошноту вплоть до приступов рвоты. Вопрос о том, как поменять "обои" в Windоws вызывает желание перерезать горло вопрошающему.

Закон программирования № 13. У большинства людей, нуждающихся в твоей помощи, причина ошибки в работе программы чисто генетическая.

Закон программирования № 14. HTML, HTTP, FTP, SMTP, TCP/IP, RTFM и т.д. - это слова, а не аббревиатуры.

Не знаю, откуда (с)перто, но забавно.

Работа с sqlite в С#. Часть 2. Опыты. Выводы.

10 сент. 2009 г. | | |

Итак, дошло время до практической части. Которая меня, скажем прямо, огорчила.
Так как хотелось использовать в своем проекте LinQ, а при попытке создать dbml-файлик штатными средствами студии выскакивает окошечко с ошибочкой (см. рис. ниже), то будем генерировать dbml с помощью DbMetal, о котором упоминалось в предыдущей части цикла.
Для начала создадим нашу базу данных, которая будет состоять из двух таблиц - Journal, главная таблица, в которую будут записываться факты поставки по конкретной дате, и таблица Items, в которой будут детали поставок по конктретной дате.

CREATE TABLE "journal" ("ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "Date" DATETIME DEFAULT CURRENT_DATE);
CREATE TABLE "items" ("ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "journalID" INTEGER NOT NULL , "supplier" VARCHAR DEFAULT supplier1, "store" VARCHAR DEFAULT store1, "amount" FLOAT DEFAULT 0)

Теперь сгенерируем dbml файл и подключим его в проект. Для генерации dbml напишем небольшой batch-файл, чтобы ручками впредь не выполнять эту операцию. Во-первых, в папке, где наша база, нужно расположить DbMetal.exe и библиотеки, которые он использует. Там же должен располагаться make_dbml.bat со следующим содержимым:

@echo on
DbMetal.exe -dbml:sample.dbml -provider:Sqlite -conn="data source=sample.sqlite"
dbMetal.exe -code:sample.designer.cs -namespace:SampleDataContext -provider:Sqlite -conn="data source=sample.sqlite"

Добавляем сгенерированный sample.dbml в проект (правый клик по проекту - Add->Existing item...).
Так как мы пишем тестовое приложение, которое, естественно, не может затронуть все аспекты, скажу о некоторых отрицательных моментах, с которыми мне довелось столкнуться. Во-первых, не поддерживается тип Boolean. Долго пришлось возиться в поисках проблемы - резко началось рушиться приложение, а оказалось, всего-навсего, не sqlite не поддерживает тип Boolean, который использовался в одной из таблиц базы данных. И, хоть альтернативу логическому типу очень легко найти (использовать тот же varchar (1)), все же очень неприятно. Во-вторых, (но это уже проблема не самого sqlite), при dbmetal почему-то не генерирует представления :( Вот так просто нас лишили крутой возможности. Опять же, ручками все делается. Но как-то неспортивно. После ковыряния в исходниках dbmetal, которые лежат в открытом доступе на svn, и перекомпиляции с включеной опцией views, стали генерироваться пустые классы. На этом решено было не тратить больше время на всякую ерунду. Ведь существуют платные хорошо работающие альтернативы, если кому надо.
И так, вернемся к нашему приложению. Его задача - отображать по выбранной дате все поставки за этот день. ГУИ будет таким:
TreeView - для отображения списка дат
ListView - для отображения поставок по датам
Теперь, собственно, будем все это оживлять.
Создадим класс DBClass, который будет заведовать работой с бд. Код:

class DBClass
{
private Main _connection = null;

public DBClass()
{
_connection = new Main(new XSqlConnection("Data Source=sample.sqlite"));
}

public List GetJournal()
{
List items = new List();
items = _connection.Journal.ToList();
return items;
}

public List GetItems(int journalId)
{
List items = new List();
items = _connection.Items.Where(i => i.JournalID == journalId).ToList();
return items;
}

public Items AddItem(Items item)
{
_connection.Items.InsertOnSubmit(item);
_connection.SubmitChanges();
return item;
}

public Journal AddJournal(DateTime date)
{
Journal item = new Journal() { Date = date };
_connection.Journal.InsertOnSubmit(item);
_connection.SubmitChanges();
return item;
}

public void DeleteItem(int id)
{
_connection.Items.DeleteOnSubmit(
_connection.Items.SingleOrDefault(i => i.ID == id)
);
_connection.SubmitChanges();
}

public void DeleteJournal(int id)
{
_connection.Journal.DeleteOnSubmit(
_connection.Journal.SingleOrDefault(i => i.ID == id)
);
_connection.SubmitChanges();
}
}

Теперь, все, что нам остается - брать и использовать методы класса в форме.
Инициализируем наше дерево:

private void InitTree()
{
foreach (Journal item in db.GetJournal())
{
AddJournalDate(item);
}
}

private void AddJournalDate(Journal item)
{
TreeNode node = new TreeNode(item.Date.Value.ToShortDateString());
node.Tag = item.ID;
tvJournal.Nodes[0].Nodes.Add(node);
}

Теперь, напишем обработчик события NodeMouseDoubleClick для отображения поставок по выбранной дате:

private void tvJournal_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (tvJournal.SelectedNode != null && tvJournal.SelectedNode.Tag != null)
{
int journalId = 0;
if (int.TryParse(tvJournal.SelectedNode.Tag.ToString(), out journalId))
{
lvItems.Items.Clear();
foreach (Items item in db.GetItems(journalId))
{
AddItem(item);
}
}
}
}
private void AddItem(Items item)
{
ListViewItem lvi = new ListViewItem(new string[] { item.Supplier, item.Store, item.Amount.ToString() });
lvi.Tag = item.ID;
lvItems.Items.Add(lvi);
}

Теперь научим наше приложение добавлять дату в список и удалять дату. Для удаления даты добавим триггер в таблицу Journal:

CREATE TRIGGER "main"."OnDelete" DELETE ON journal BEGIN Delete From items Where items.journalID = deleted.ID; END

Код обработки клика для кнопки "Удалить выбранную дату" выглядит так:

private void button2_Click(object sender, EventArgs e)
{
int journalId = (int)tvJournal.SelectedNode.Tag;
db.DeleteJournal(journalId);
tvJournal.Nodes[0].Nodes.Remove(tvJournal.SelectedNode);
}

Ниже приведены обработчики событий клика по кнопкам "Добавить поставку" и "Удалить выбранную поставку" соответственно:

private void addItemToJournal_Click(object sender, EventArgs e)
{
int journalId = 0;
if (int.TryParse(tvJournal.SelectedNode.Tag.ToString(), out journalId))
{
Items item = new Items() {
Amount = float.Parse( tbAmount.Text ),
Store = tbStore.Text,
Supplier = tbSupplier.Text,
JournalID = journalId
};
AddItem(db.AddItem(item));
}
}

private void DeleteItemFromJournal_Click(object sender, EventArgs e)
{
if (lvItems.SelectedItems.Count > 0)
{
int itemID = (int)lvItems.SelectedItems[0].Tag;
db.DeleteItem(itemID);
lvItems.Items.Remove(lvItems.SelectedItems[0]);
}
}

Вот и все. Поигрались и хватит :) Весь рассмотренный функционал можно воплотить и через ADO.NET, без пляски с бубном вокруг LinQ, но вы же сами знаете, что так не интересно :)
Исходник можно скачать тут.

Работа с sqlite в С#. Часть 1. Инструменты.

9 сент. 2009 г. | | |


Инструментов для работы с этой хоть маленькой, но удаленькой БД существует много. Есть и платные, и бесплатные решения. Полный список инструментов - и врапперов, и конвертеров, и менеджеров - вы найдете тут. Данная статья не дает на полный обзор и сравнительную характеристику всех средств для работы с sqlite. Так как в статье рассматривается версия БД под Windows, то инструменты, соответственно, для этой платформы.
Начнем с System.Data.SQLite - провайдера, обеспечивающего полноценную поддержку ADO.NET 2.0/3.5, поддержку design-time в VS, а так же много чего другого, о чем можно почитать тут http://sqlite.phxsoftware.com/
Еще один Linq2Sqlite провайдер - это DbLinq. Но последний официальный релиз за сентябрь 2008 года, хотя в свн проект постоянно обновляется. Адрес проекта http://code.google.com/p/dblinq2007/
Следующий продукт для работы с sqlite в .NET - это Mono (Mono.Data.SqliteClient), версия для sqlite3 которого базируется на коде предыдущего враппера. Сайт проекта http://www.mono-project.com/SQLite
Для работы с sqlite в Visual Studio компания DevArt приготовила специальный коннектор -
dotConnect for SQLite - который имеется в облегченной standard free-версии (нет поддержки linq и некоторых других фич) и в триал professional версии за 149.95$ для одного человека. Скачать бесплатную версию можно по ссылке http://www.devart.com/dotconnect/sqlite/download.html. Тут же находится документация и примеры.
Как говорится на сайте разработчика, dotConnect поддерживает ADO.NET Entity Framework, LINQ to Sqlite, так же есть специальные фичи для Winforms (гибкое связывание данных и др) и для ASP .NET, есть поддержка редактирования БД из VS, что очень и очень удобно.
Далее, удобная штука для работы с sqlite - SQLite Manager - это аддон для Firefox, который можно скачать по ссылке https://addons.mozilla.org/ru/firefox/addon/5817. Добавлена поддержка Firefox>3.5, что очень порадовало. Удобное дерево объектов БД, удобные диалоги при работе с БД (только слегка маниакальные, имхо), возможность экспорта таблиц/представлений/БД в csv/xml/sql формат, возможность импорта данных из этих же форматов и другие фичи предлагает данный плагин. Удобная и бесплатная вещь.
Следующая тулза - SQLite Administrator - поддерживает больше форматов для экспорта ( XLS / CSV / HTML / XML), есть функция мигрирования с QLite2 БД в SQLite3. Радует поддержка русского интерфейса. Полный список фич, а так же скачть программу можно по ссылке http://sqliteadmin.orbmu2k.de/
Так же для работы с sqlite есть удобная вещь SQLite Maestro, но это уже из области платных программ. Домашняя страничка программы с описанием всех фич находится по адресу http://www.sqlmaestro.com/en/products/sqlite/maestro/
Есть еще вот такая бесплатная программулина SQLite2009 Pro Enterprise Manager, живущая по адресу http://osenxpsuite.net/?xp=3&uid=managementtools, по этому же адресу живет и ее описание.
И, самая удобная, на мой взгляд тулза, это SqliteDeveloper от компании SharpPlus. Скачать можно тут http://www.sqlitedeveloper.com/sqlite-developer-sqlite3-database-manager

Работа с sqlite в С#. Введение.

8 сент. 2009 г. | | |

Бывают проекты, в которых необходимо хранение данных, объем и структура которых делает хранение в обычных файлах неудобным, а использование СУБД - слишком громоздкое и дорогое решение. Представьте, для программы весом в пару мегабайт, которая спокойно умещается на флешке, ставить SQL Server. Немного утрировано, но всё же...
Для решения подобного рода проблем очень хорошо подходят embedded-БД (встраиваемые БД), например, sqlite, firebird или из области объектных бд - db4o. Конечно, им всем далеко до полноценных СУБД, но не для конкуренции с ними создавались встаиваемые БД, а для облегчения распространения приложений, использующих небольшие БД. Понятно, что для достижения этой цели пришлось чем-то жертвовать, и каждый жертвовал, чем мог :) Так как разговор в данной статье должен идти о первой из списка embedded-БД - sqlite, то давайте как раз посмотрим, чем же порадуют нас разработчики.
Как ожидается из названия, данная embedded-БД должна быть лёгкой. Это правда - размер подключаемой библиотеки со всеми фичами, как говорят разработчики, меньше 300 КБ. К тому же, с ней легко работать, ее легко внедрять в создаваемое ПО, ее легко администрировать и еще много таких "легко". Sqlite распространяется на условиях "открытого исходного кода", скачать ее можно с официального сайта http://www.sqlite.org.
Чем хороша sqlite:

  • Поддержка языка запросов версии SQL92 (без особенностей типа процедур)
  • База данных сохраняется в одиночном файле на диске
  • Файл базы данных можно свободно разделить между процессами (например, тот же embedded firebird блокирует файл БД для монопольного использования)
  • Поддерживает базы данных размером до 2-х терабайт (241 байт)
  • Размеры строковых данных и BLOB данных ограничены только памятью
  • Нет никакой внешней зависимости от других библиотек
  • Поддержка операционных систем WINDOWS (практически все версии начиная с WIN95), *unix
  • Распространяется совершенно бесплатно

Чем плоха sqlite:

  • не Oracle или MS SQL.

Естественно, SQLite не предназначена, чтобы быть двигателем базы данных предприятия, это не вариант для использования в крупных проектах, разве как временную резервную БД (и звучит это даже как-то по-мазохистски). Как написано на официальном сайте движка, sqlite не предназначена, чтобы заменить Oracle, но для замены fopen().