четверг, 15 июля 2010 г.

New metadata and OOP features in MacroTSQL

New feature 1.

Normal reflection over XML attributes (work on every object type whick keeps it's source code in sys.sql_modules (all except tables)

Assume that such view was created:

<myvar val1="1">2</myvar>

create view myview as select 1 as id

Now you can use comdiv.schemaview to find and test it:


So result will be :
type fullname col1 col2
VIEW dbo.myview 2 1

works for now above SP,F,T,V, not for tables.
Supports visualization of
name, module->name, module->class, module->method attributes,
events and some others
sygnal about 'isinterface','isprivate' due to applyed schema

For MacroSQL created object additionaly SourceSQL column provided
which contains pure sql (no declaration) of code before prepocessing

is FxCOP-like stored procedure that analyzes schema through comdiv.schemaview and search for errors, mistakes and not well formed metadata.

For example - after such view was created, i see:
exec comdiv.validateschema
=VIEW-----|-dbo.myview--|---40-----|--40-------|-module is not defined
=VIEW-----|-dbo.myview--|----5-----|--60-------|-best practice is to define class and method of object =


<myvar val1="1"></myvar>
<module name='mytestmodule' class='stub' method='sampleview' />

create view myview as select 1 as id

will match requirements

New feature 2.

Object-like style of calling inside MTSQL-style procedures.

Given such procedure (named due to some schema needs or historically):

<module class="utils" method="printdate" />
create proc dbo._SP_print_date as begin
declare @now datetime set @now = getdate()
print @now

in M-TSQL procdures you can call it not by real name, but by 'class'
NOTES: class names are applyed only if they are already exists!!!

create proc _ as begin
exec utils.printdate

Code is very readable and is good for migration
You need just keep class->method names, but safely rename real object (with following recompilation of MTSQL code)

среда, 14 июля 2010 г.

MTSQL : Strange '_'-named objects, why?

Almost all procedures, functions and other programmatical stuff in Macro T-SQL core and descendant scripts are  implemented in following mode:

this is my real proc...
create proc _ as begin
         -- some stuff

Why we use such strange syntax except usual :

create proc procname as begin
/* this is my real proc... */
         -- some stuff


T-SQL not have CREATE OR REPLACE constructions in it. So real-world scripts are looks like:

if object_id('procname') is not null drop proc procname
create proc procname as begin
         -- some stuff

Where are some visible problems in such code:
  1. name is repeated 3 times - so it's not good when you copy paste it or correct names, and it's anti-pattern
  2. you MUST execute this code in 2 commands - it is not big problem in SQLWB, but when you work from program client you must keep it in mind and perform 'GO' parsing and batching code
But in MacroSQL-style definition we have problems solved:
  1. no ambiguity - name defined at one place
  2. one command execution - cleaning up of objects performed by MTSQL DDL Trigger which drops object and then recreate it by provided SQL ('_' object dropped TOO, so you ALWAYS can create it

Usual (not AFTER) DDL triggers are executed not AFTER  COMMIT of creation, but AFTER CREATION ITSELF, so object MUST BE CREATED. If we try to call create proc procname, we still will caught error if such object exists even if we use DDL trigger for CREATE_PROCEDURE. (no analog of 'INSTEAD OF' ralized for DDL triggers).


We decide to use '_' style - it's realy mimimalistic object name, and we havn't see real databases with object called 'dbo._' 

As alternative we choose it from another syntax:

create proc procname_mtsq as begin
         -- some stuff
Trigger must have response to _mtsql suffix and drop it with creation of normally named object. But it's very bad:
  1. less readable  - no visible difference with usual definitions
  2. less ecological - we not have reserved just unusable '_' name, but whole NAMING RULE
MacroTSQL Trigger and Preprocessors that it calls, may be broken for usual syntax, they awaits some attributes (not provided by usual code), they perform some large operations on source code.
If such trigger will work on everything that occures in given DB, it will be dangerous for usual schemas and usual scripting.
By '_' name we have expressive and easy to use 'keyword' which differentiate Macro TSQL-awared object creation scripts from usual. MTSQL works only with it's stuff, not on usual procedures. 

QUESTION 3. What to do if my database have object named 'dbo._'?
Answer 1.: if it is possible - rename it
Answer 2 : if impossible - rewrite MTSQL source code for this database to use another name to define MTSQL objects

понедельник, 12 июля 2010 г.

NEW! Method declarations in Macro TSQL

Here is last submit info (Вот что было в последних обновлениях):

1) NEW method declaration support for interfaces
2) FIX _drop now can drop triggers
3) FIX procedure renaming applyed correctly (only in outer declaration)
4) FIX pseudo object '_' now dropped when core module loaded
5) NEW syntax shugar - allow call to dynamic sql in short style :

exec _ '<<< select * from {{@table}} where {{@field}} = ''{{@value}}'' >>>'
6) UPG addition comdivpreprocessor.x300_table_interface_parameters_embeder - adds parameters to interface definitions if not provided manually (@table and @useconstraints parameters)
7) NEW safe and simple procedures to ensure (create if not exists) of filegroups and files of database
8) NEW comdiv.mtsql.core.interfaces.sql - module - some our best practices of table schemas (especially for hibernate mapping), expressed as comdiv table interfaces

What is most interesting? (Что наиболее интересно?)
method declarations (Определения методов в интерфейсах)
Look at this code:
<field name='code' type='nvarchar(255)' constraint='not null unique default cast(newid() as nvarchar(255))' />
<method name="id">
        create function __ (@code nvarchar(255)) returns bigint as begin
            return (select top 1 id from THIS where code = @code )
<method name="code">
        create function __ (@id bigint) returns nvarchar(255) as begin
            return (select top 1 code from THIS where id = @id )
create proc _ as begin return end

if(object_id('__X') is not null drop table __X
_table '__X'
_interface '__X', 'code'
insert __X (code) values ('a')
select dbo.__X_id('a')           -- 10
select dbo.__X_code(10)      -- 'a'

Significant changes:
1) methods a totally defined on declarative maner
2) automatical name generation - don't need to copy in method implementation (use pseudo name __ instead)
3) special 'keyword' THIS that means table to which interface is applyed

Значимые изменения:
1) методы полностью формируются в декларативной части
2) автоматическая генерация имен - не надо дублировать в реализации метода, используется псевдо-имя __
3) специальное "ключевое слово" THIS - обозначает целевую таблицу, к которой применяется интерфейс

Macro T-SQL project published (en)

More than 10 years i'm working with MS SQL

Something was upgraded during this years, and MS SQL 2005 is exactly good server for many and many projects that we develop and support.

But working with PostGres, system programming on C#, Boo and others give as not very good thing to think about. It's that T-SQL is not so good language as we want it to be... Not much readable, with some ugly constructions and everyday 'snippets' to do some simple stuff.

We were'nt want to live with this forever and wait MS to give as something fantastic in SQL 2016, but:

  1. T-SQL is what it is - well complicated, but not extensible, not-declarational language and we cannot avoid it.
  2. I hate any code-preparing utils that you MUST to call if you want to apply some DSL - what if i want to call SQL from APP - i must to supply it with very_good_utility.exe? and call it ?
  3. Schema generator programs is far more ugly thing even than codegenerators...
  4. Using of .NET assemblies looks mo prety, but... it's hard to support too and cause it's own problems
  5. We like to solve problem in MS SQL 2005 itself and with T-SQL itself
In a moment we have 'evrica!'

Module we wrote is not a part of comercial order, is not selfish product, so I decide to publish it as open source.

Go to  http://code.google.com/p/macrotsql/.
Discussion at:

By using special stored procedures and DDL triggers (without any .NET assembly or custom tool) you'll get folloing framework:

  1. embeded XML documentation as in C#
  2. declarative attribute programming (inspired by C# and Boo mete-attributes)
  3. stored procedures and function SQL extensible preprocessor framework
  4. object-oriented support for table schema definition (very wanted after POSTGRE, inspired by prototype.js :) - we define some set (with inheritance) of 'interfaces' that then are applyed to target table (extends it)
  5. prepared set of preprocessors for some every day tasks:
  • tracing of proc enter and leave
  • wrapping procedure body in transaction
  • explicite (in text) line numbering (for quick finding place of error from error comment)
  • support fo  foreach macro block instead of ugly native  work with cursors (maybe worst thing in T-SQL)
Look at project, try it, send me feedback and patches. Wish that project will be usefull for you and you will be usefull for project :)

Проект Macro TSQL запущен (ru)

Более 10 лет работы с MS SQL не могли пройти даром.

Шли годы и многое менялось и движок становился лучше и краше и в принципе ни один из текущих коммерческих проектов и не требует ничего более SQL2005...

Но все же работа в параллельных проектах на PostGRES, системное программирование в C# привело к мысли, что T-SQL это уже довольно отсталый и неудобный язык для работы с БД, требущий много избыточного кода.

С этим не хотелось мириться, но:

  1. T-SQL какой есть такой есть - не расширяемый, далекий от декларативности, с достаточно строгими и избыточными конструкциями
  2. Очень не люблю всякие спец-утилиты для конвертации кода или что хуже всего - всякие программки, которые цепляются к базе и что-то там делают
  3. Подцепление всяких хитрых .NET сборок - это конечно здорово, но существенно снижает переносимость и усложняет сопровождение баз.
  4. Хотелось все делать просто с базой, просто из T-SQL
В какой-то момент нам это удалось.

И так как проект не связан с каким-то коммерческим заказом и не является продуктом сам по себе, решил опубликовать его в опен-сорс. Может кому пригодится.

Зайдите на:  http://code.google.com/p/macrotsql/.
Обсуждение в вейве:

Там в целом все понятно:

При использовании специальных хранимых процедур и триггеров (без какого-бы то ни было вмешательства расширений .NET) вы получаете инфраструктуру для:
  1. встроенного документирования функций в XML нотации - а-ля внедренной документации С#
  2. декларативного программирования в форме XML атрибутов (тоже навеяно С#, хотя скорре это ближе к макроатрибутам Boo так как влияют больше на компиляцию, нежели чем на работу процедуры)
  3. инфраструктуру для использования готовых и создания своих собственных перепроцессоров SQL для хранимых процедур и функций
  4. объектную модель для формирования схемы таблиц - есть возможность создавать "интерфейсы", наследовать их друг от друга , а затем применять к таблицам с формированием наборов колонок, триггеров, специальных функций
  5. готовый набор препроцессоров для ряда типовых задач:
  • быстрое подключения трассировки на входе и выходе из процедуры
  • обрамление тела процедуры в транзакцию
  • явное нумерование строк (облегчает потом поиск места возникновения ошибки)
  • поддержка простого в написании блока foreach в качестве макроса для работы с курсорами (которая в исходном T-SQL сделана просто ужасно)
Смотрите проект, пишите, присоединяйтесь к проекту. Надеюсь он понравится многим программистам на T-SQL и я получу тоже что-то полезное в проект