пятница, 27 мая 2011 г.

Feed Me Oil

Today, June 2, 2011 is important day for us, AnjLab team, big milestone. Today, under HolyWaterGames brand, together with Chillingo / EA, famous games publisher, we released ‘Feed Me Oil’ game for iPhone, iPad and iPod Touch. It is available at Apple AppStore


Behind this event more than year of hard work, starting with experiments with liquid physics and finishing with many marketing activities. I can say, this game is unique on iOS market from technological point of view. It is based on math modeling of liquid behavior; ‘oil’ in the game is not animation or set of pre-set templates, it acts as real oil – stream, distribution, mixing. In result, each level of the game has endless number of solutions and space for improving your score.

First version of the game was strong and complex, amusement for real geeks. We saw the game from our point of view, tried to make it attractive to ourselves. Many thanks to Chillingo guys, they looked to the game as average user and gave us many useful suggestions how to improve it, make more friendly. Also we integrated Chillingo’s Crystal technology, which allows users to share results and compete with each other.

Thus, the game was announced on Game Developers Conference 2011 in San Francisco in Fabruary, published as upcoming be Chillingo in May. We have very positive and promising reaction on this. We hope the game will be popular. Maybe as popular as Angry Birds or Cut the Rope. However, nobody knows. Even experienced marketing guys confess the fact: it is very hard to predict success or fail of a game, too many factors influence on it. We have good reviews and preliminary estimates, but will see - now it will be going on.

At least we got very good experience. I mean two things: experience in development for iOS, and experience in creating product from the scratch, from initial idea to completed product for so specific and mature market, which AppStore is. Will keep moving in this direction, updates and new versions of Feed me Oil are already planned.

понедельник, 11 апреля 2011 г.

Integrate Reporting Services 2008 with SharePoint Server 2010

Short instruction:

  1. Install MS SQL Server Reporting Services (SSRS) 2008 R2 in SharePoint Integrated mode. The service should run under domain account, do not use built-in account like SYSTEM.
  2. Enable reporting services for SharePoint farm. Go to SharePont Administration Center, open General Application Setings - Reporting Services - Add Report Server. Specify RS URL (http:///reportserver), domain account to connect. If feature activated successfully for all site collections, on Defaults settings page make sure parameters 'Enable Windows Authentification' and 'Enable RS ActiveX sownload' are on.
  3. Create reports library. Open your SharePoint site and create new Document Library (by default), open Library settings - Advances Settings and set 'Allow management of content types' on. Return to library settings and click 'Add from existing types' link in Content Types settings. In dialog, choose 'Reporting Services content types' group and add all available types.
  4. Deploy reports with SQL Server BI development studio. In your report project properties, set TargetServerURL = http://server, TargetReportFolder = http://server/site/list. The same for TargetDataSourceFolder. In common case you can use different lists to store reports and datasources. Instead VS you can deploy with PowerShell using this script.
  5. You can add report on any page of SharePoint site with special RS webpart.

пятница, 24 сентября 2010 г.

SQL Server: iterations vs. set operations with XML

I previous post I published some common information about AnjLab.FX.SQLServer, set of useful tools for SQL development. Now I would highlight one small research I did during implementation of some functions.

I always consider SQL programming language as set operations as opposed to procedural and object oriented languages. Yes, it includes procedural structures, which allows you to create complex algorithms, but core, nature of SQL approach are set operations – union, join, except, intersect, etc. If something can be done with set operation I prefer this way. In the most cases handling all scope at once is more effective than processing row by row, sometimes, much more effective.

SQL Server 2005/2008 provides ability to use XML data type, store, read and write XML data, transform it to / from relational structures. However, are set operations for XML data as effective as for relational structures? For comparing I do not want to use simple trite abstract examples. Let’s look at inverse tasks I met in practice in several projects – converting rowset column values to string with delimiters and convert string with delimiters to one-column rowset.

Let’s consider first task and use as input rowset of 10K records. For creating it I use AnjLab.FX.SQLServer function getEmptyRowset which returns one-column rowset of given number of records.

Iterations:

declare @String nvarchar(max), @Delimiter nchar(1), @i int

declare @Table table ([Value] nvarchar(10))


insert into @Table select ltrim(str(RecordID))

from fx.GetEmptyRowSet(10000)


set @String = space(0)

set @Delimiter = N','


declare A cursor for select [Value] from @Table

declare @Value nvarchar(10)


open A

fetch next from A into @Value


while @@fetch_status = 0

begin

set @String = @String + @Delimiter + @Value

fetch next from A into @Value

end


close A

deallocate A

select @String

Set operation:

declare @String nvarchar(max), @Delimiter nchar(1), @i int

declare @Table table ([Value] nvarchar(10))


insert into @Table select ltrim(str(RecordID))

from fx.GetEmptyRowSet(10000)


set @String = space(0)

set @Delimiter = N','

set @String = (

select [Value] + @Delimiter as 'data()'

from (select [Value] from @Table) as A

for xml path(''))


select @String

Here is funny trick – we convert relational data to XML with empty structure (xml path(‘’)), which is actually just a string. Profiling (I recommend to use open source AnjLab SQL Profiler) shows duration 1400 ms in first case vs. 350 ms for second. Set operation with XML is 4 times faster than iterations.

Next, focus on inverse task, and use string of the same 10K values. I omitted code for creating such long string in examples below and use just set @String = N'1,2,3,4' to simplify them.

Variant one - Iterations:

declare @String nvarchar(max), @Delimiter nchar(1)

declare @Table table ([Value] nvarchar(max))


set @String = N'1,2,3,4'

set @Delimiter = N','


while charindex(@Delimiter,@String) > 0

begin

insert into @Table values(substring(@String,1,charindex(@Delimiter,@String)-1))


set @String = substring(

@String,

charindex(@Delimiter,@String) + 1,

len(@String) - charindex(@Delimiter,@String))

end

insert into @Table values(@String)


select [Value] from @Table

Variant two – set operation with direct reading from XML:

declare @String nvarchar(max), @Delimiter nchar(1)


set @String = N'1,2,3,4'

set @Delimeter = N','


;with Data(Test) as (select Test = cast(

N'<1>' +

replace(@String, @Delimiter, N'<1>') +

'' as xml))

select Nodes.Node.value(N'.', N'nvarchar(255)') as [Value]

from Data

cross apply Test.nodes (N'//a') Nodes(Node)

What we have done here:

  • Convert string value to XML by replacing delimiters with XML tag <1>
  • Convert scalar string variable to rowset using select. Note, instead of scalar variable we can use table and handle multiply strings.
  • Define rowset as CTE (common table expression) Data. This step is actually, redundant, it just simplifies the code.
  • Using cross apply select node <1> values from XML

Variant three – set operation with openxml:

declare @String nvarchar(max), @Delimiter nchar(1), @docHandle int,

@XML xml


set @Delimeter = N','

set @String = N'1,2,3,4'

set @XML =

cast(N'<1>' +

replace(@String, @Delimiter, N'<1>') +

N'' as xml)


exec sp_xml_preparedocument @docHandle output, @XML


select [Value] = [text] from openxml(@docHandle, N'/root/1')

where [text] is not null


exec sp_xml_removedocument @docHandle

Here we use system procedure call to prepare XML for openxml function. Unfortunately, this makes this variant not applicable to use inside functions.

Let’s compare results: first variant 1600 ms, third – 50 seconds (!), second is endless, I have stopped waiting after 30 minutes (!!). Reading XML with set operation is incredible slower than iterations.

Conclusion is banal: XML is not native structure for SQL Server, reading data from XML is slow, sometimes, very slow operation. XML cannot be considered as replacement for relational structures, it is good only for storing small portions of loosely structured data, like settings. However, writing to XML is fast operation and can be used in such tricks like in first task.

PS. The best approaches were used for implementation FX functions getRowsetAsString and getStringAsRowset.

PPS. For sure, second task can be done with regular expressions, but there is no native support for regexp in SQL Server.

вторник, 21 сентября 2010 г.

AnjLab.FX.SQLServer

AnjLab.FX is .NET framework which includes many various useful tools for NET developers. This is open source project, hosted on GitHub. We, AnjLab team, use FX library in the most of our NET based projects and each new project supplements the library with new functions. You can use it without any restrictions.

AnjLab.FX.SQLServer is an independent part of the project, it can be used separately. It is set of tables, T-SQL based procedures, functions and scripts for Microsoft SQL Server 2005/2008. FX objects can be installed on any existing database on SQL Server, the code includes command line setup routine. In result, in given database will be created separate scheme FX where all objects will be located. No other objects or data will be affected.

Below is a list and short descriptions of the most interesting tools from my point of view:

DDL tools. Note, some FX functions duplicates standard tools, but do the same things in different style and with many options.

  • Stored procedure ScriptObject – returns DDL script for creating given programmability object (stored procedure, view, function, trigger)
  • Stored procedure ScriptTable – returns DDL script for creating given table, including keys, constraints and indexes
  • Stored procedure ScriptEncryptedObject – returns DDL script for creating given encrypted programmability object (stored procedure, view, function, trigger). The procedure works in DAC (dedicated admin access) mode.
  • Stored procedure ScriptDiagram – returns script for creating given diagram
  • Stored procedure ScriptData – scripts all data of given table as set of INSERTS. The procedure has many options.
  • Stored procedure SearchObjectByText - searches SQL Server programmability objects (stored procedures, functions, triggers,     views) by substring in object's body.
  • Script Indexing foreign key fields - creates non-clustered indexes for all fields which are used in foreign keys, if they are not indexed.

Date and time

  • Function CheckLeapYear - returns true if year of given date is leap and false in other case.
  • Function ReduceDate - for given datetime returns start or end of current hour, day, month, etc, in other words, truncates datetime.
  • Function GetPeriods - returns set of date and time periods (hours, days, months, etc) between given start and end dates.

Table valued tools

  • Function GetEmptyRowSet - returns rowset with defined number of record.
  • Function GetStringAsRowSet - returns rowset from string with delimiters

Other

  • Function CalculateYield - returns yield (in %%), based on time period (taking into account leap years) and revenue.
  • Function ConvertVarbinaryToVarcharHex - returns hexadecimal representation of binary data, using chars [0-0a-f].
  • Function Div – just divides one number by another, but handles dividing by zero and converts numbers to float

Tables

  • Countries - world countries dictionary (in Russian and English) according to ISO 3166 and Russian ОКСМ standards
  • Currencies - world currencies dictionary according to Russian ОКВ standard (Russian language only)
  • MeasurementUnits - Russian classification of units of measurement according to Russian ОКЕИ standard (Russian language only)
  • BusinessLegalForms - Russian Classification of Organizational and Legal Forms according to Russian ОКПФ standard (Russian language only)
  • IdentityCardTypes - Russian personal ID types dictionary (Russian language only)

Note, some tools are based on code created by other authors, but all copyrights and information are in place. All scripts have XML style headers with common information.

пятница, 12 февраля 2010 г.

10 лет оффшора

Не сказать, что я как-то специально что-то считал. И уж тем более, не было желания подводить какие-то итоги и строить планы по поводу некоей круглой даты. Но совершенно случайно сегодня всплыла мысль – а ведь где-то в эти дни исполняется 10 лет, как я занимаюсь разработкой в оффшоре. А точнее, работаю ПМ-щиком в оффшорных командах.

2000-й год. Интернет – Анекдот.ру, РБК, Альтависта, аська, что еще тогда было? Работаю в администрации города. Уже далеко не студент – главный специалист, какие-то переспективы, костюм с галстуком. Проекты довольно интересные, информационный департамент не так давно зародился, все развивается. Может быть странно, но я очень хорошо отношусь ко всем предыдущим местам работы. Эмоции, конечно, разные бывали, но в сухом остатке всегда позитив. Всегда уходил с «багажом» в голове, который давал возможность сделать следующий шаг. Но… зарплата в 70 долларов, да и ту задерживают. Денег тотально не хватает. Когда уходил, не раз слышал – зачем уходить от стабильной зарплаты непонятно куда и зачем. До сих пор остались коллеги, с которыми работал тогда – до сих пор примерно на тех же должностях, делают те же задачи, живут теми же проблемами - время остановилось. Для меня же сменилось несколько эпох.

Итак, обшарпанная комнатка, где собираемся несколько раз в неделю. С бору по сосенке набранная команда, странный заказчик-американец, странные проекты. Так начиналось мое «оффшорничество». Это я сейчас с иронией об этом говорю, а тогда был драйв, небо в алмазах, ожидание переспектив, работа ночами до утра. Ничего мы толком не знали и не умели, но искренне считали себя лучшими и страстно стремились к успеху. Мне повезло, я попал в компанию, где были очень адекватные руководители, у которых многому научился. В то время сколько нибудь организованной ИТ индустрии во Владимире просто не было, мы же занимались разработкой софта на экспорт, да и контакты первые у нас были, каких ни до, ни после не было – один профессор Гарварда, другой миллионер. Увы, ухватили только конец того счастливого времени первой интернет – волны, через несколько месяцев лопнул пузырь доткомов, и пришлось спускаться с неба на землю. А первая поездка в Штаты – это же шок. Это сейчас съездить в Париж на неделю в порядке вещей, тогда было другое время. Жили беднее и проще. Даже магазинов самообслуживания во Владимире не было ни одного. А там – совсем другая жизнь.

7 лет проработал на одном месте, пережил вместе с компанией взлеты и падения, надежды и разочарования. Ушел, потому что перерос свои рамки в ней, потому что снова, как и в 2000м что-то стало двигаться в голове, потому что пришло время. Ушел в свой бизнес, почти на пустое место по сути. Снова говорили о рискованности ухода от стабильного заработка и снова не прогадал, ни с заработком, ни с ощущением осмысленности жизни.

10 лет это срок. Больше всего изменился интернет. Если изначально это было не более чем средство ограниченной коммуникации и место для поиска информации, то сейчас он органично заполняет все, ты буквально живашь в нем. Сменилось несколько поколений технологий программирования. Но за десять лет ни написал ни строчки кода приложений, только консервативные реляционные базы данных. И правильно, наверное, все равно мне за ними не успеть, лучше заниматься тем, что лучше получается и приносит удовлетворение. А моим коньком оказалась организация и управление рабочей группой. С профессиональной точки зрения 10 лет можно разделить на два, примерно равных периода. Сначала я верил в процесс, в то, что стоит правильно все организовать, и успех придет автоматически. Во второй «фазе» пришло понимание, сто процесс нельзя ставить во главу угла, он должен быть адекватным обстановке и не более того, должен гибко именяться под различные ситуации. Процесс не должен заслонять людей.

Так получилось, что 10 лет работал только на американцев. Европа для меня так и осталась terra incognita, западнее Варшавы никогда не был. И менталитет европейцев остается для меня загадкой. Зато узнал США. Был там раз 12 или 13 – Бостон, Нью-Йорк, Чикаго, Сан-Франциско. Красивые, интересные, черт возьми, места. Не могу сказать, полюбил эту страну или восторгался ей. Но проникся, мне она стала как-то близка. Великая страна, чтобы ни говорили. 10 лет назад по английски знал только отдельные слова, сейчас могу, хоть со скрипом, но общаться. Работа на американцев и возможность увидеть все своими глазами, дали уверенность в себе, начисто избавили от комплекса провинциальности, от ощущения, что вот ты здесь изобреташь свой велосипед, а где-то идет настоящая жизнь.

Проекты… их было много, на любой вкус. В первых работах на «заокеанских миллионеров и профессоров» был внешний шик, но не было понимания кому, зачем и почему это нужно. Получаешь особый драйв от чисто практических проектов. От осознания того, что за десятки тысяч километров человек, которого ты знаешь, будет видеть вот этот самый интерфейс, и может вспомнит и тебя. Надеюсь, хорошим словом. Принципы работы с заказчиками, кстати, изменились мало. Люди, в отличие от технологий, почти не меняются.

Денег много не заработал. Да и теперешний офис принципиально мало отличается от того, что был 10 лет назад. Но ни разу не пожалел о сделанном выборе, получил колоссальное удовольствие, занимаясь тем, что у меня неплохо получается. А сейчас, работая в команде AnjLab получаю кайф еще и от ощущения свободы, от того,ты сам в ответе за все, все зависит от тебя.

Вот как то так!

четверг, 29 октября 2009 г.

Мысль о кризисе

Смотришь новости и возникает легкое дежавю – растущие цены на нефть, растущий рубль – где то это уже было. Все вернулось обратно? – вряд ли. На днях занимался обновлением информации на нашем сайте – много новых проектов, новых заказчиков и партнеров – и возникла мысль, а ведь, по сути, это итоги прожитого кризисного года. Человек больше всего боится неизвестности, самое непростое время для нас было в начале, когда приостановилось несколько проектов и совсем неясно было что ожидать. А потом, ничего, нащупали почву под ногами и пошли вперед. В ноябре перехали в новый офис, в декабре запустили Планету, наш первый серьезный венчурный проект. За год не потеряли связей со старыми партнерами, начали отношения с тремя новыми (два в США и один в России), счет проектам пошел на десятки. В то время, как масса компаний вокруг «рубят косты» и стараются выжить, мы как-то незаметно расширились численно, увеличили обороты, осваиваем разные «смежные» виды деятельности, работаем над собственными идеями. В чем причина такого относительного успеха – удача, стечение обстоятельств? Наверное, да, но полагаю, дело не только в этом. За год я насчитал пять совершенно разных проектов, которые объединяет одно – они достались нам в наследство от других разработчиков, заказчик решил сменить коней на переправе. Причины совершенно разные – некоторым нашим предшественникам нужно оторвать руки и настучать ими по голове за те убогие, неработающие, дефективные по своей архитектуре решения, которые они понаделали. Но были и случаи, когда решения были неплохие, исполнитель проффессионален, но оказалась ни к черту организационная составляющая – контакт и взаимопонимание между исполнителем и заказчиком оказались напрочь утраченными, они просто говорили на разных языках и не понимали друг друга. И все эти пять проектов удалось вывести из тупика. В этом, наверное, один из секретов – в адекватности, способности к нешаблонным решениям, эффективности.

И мы будем стараться сохранить и укрепить свою «марку». На наше счастье, наш рост был постепенным, без резких колебаний, нам удалось избежать связанных с этим проблем. И в дальнейшем, надеюсь, будем двигаться в том же направлении – качество важнее количества. Наш бизнес сродни ремеслу. Есть большие компании-фабрики которые с разной степенью успешности применяют промышленные, обезличенные методы разработки, конвейер. К нам же приходят люди, которым нужен продукт на заказ, по мерке. Попытайся мы применить «промышленные» методы получится дорогое барахло. Только нестандартный подход и уважение к тому что ты делаешь дадут результат.

Цель этого поста не самовосхваление. Все случается так, как должно случится. Кризисы неизбежны по самой природе экономики и они ясно показывают все слабые стороны. Кризисы обостряют конкуренцию и дают дорогу более дерзким, эффективным. Тем, кто оказался в нужное время в нужном месте. Разные компании переживают кризис совершенно по разному – Microsoft падает, Google крепко стоит на ногах, Apple неудержимо растет. Надеюсь, мы в правильной компании.

четверг, 16 июля 2009 г.

20 лет компании ИнрэкоЛАН

Поздравляю наших коллег из владимирской компании ИнрэкоЛАН с 20-летием фирмы. 20 лет это огромный срок, особенно в непредсказуемой российской действительности. Столько может "прожить" только нестандартная компания, которая гибко лавирует в океане бизнеса, оставаясь всегда на "гребне волны". 10 лет назад, после кризиса 98-года произошел один такой поворот и core business компании стала разработка ПО на заказ. Это были времена, когда искали в Интернете Альтавистой, а коннектились по диалапу... Мне посчастливилось работать в первой команде разработчиков и я помню удивительный кураж, ощущение единства, осознание того, что мы лучшие, что мы делаем то, что никто не делал. Потом компания росла и матерела, было много интересного, но я с особой теплотой вспоминаю первые года работы в ИнрэкоЛАН. Хотя понимаю, что мы почти ничего тогда толком не знали и не умели, тыкались почти вслепую, набивая шишки. Но каков был настрой! Сейчас моя работа в нашей команде AnjLab во во многом напоминает тот "ранний" период, но на другом профессиональном и организационном уровне, с высоты накопленного опыта. И это мне нравится.

Ребятам из ИнрэкоЛАН желаю оставиться открытыми ко всему новому, не зашоренными, ищущими. Интересных вам проектов и хороших заказчиков.