otrdiena, 2011. gada 1. novembris

SQL Server "TODO" saraksts

Veidojot tādu kārtīgu procedūru/funkciju kaudzi nonācu pie secinājuma: būtu vērtīgi, ja varētu piefiksēt vēl noslīpējamās lietas tajās. Respektīvi- izveidot "TODO" sarakstu, kā to var darīt, piemēram, Visual Studio.

Tad nu ātrumā izveidoju skriptu, kurā gan ir dažas tīri interesantas nianses (rekursīvs vaicājums, cross apply saite, with encryption un dažas ne visai elegantas darbības ar teksta virkni).

Kā tas strādā
Piemēram, datu bāzē izveidotas vairākas funkcijas/procedūras:
Create Procedure usp_ExampleToDoProc
As
Begin
    -- TODO: šobrīd procedūra ir galīgi tukša..
    Set NoCount On
End
Go
Create Function fn_ExampleFunction()
Returns int
As
Begin
    -- TODO: schemadinding jāpieliek
    -- TODO: jāatrgiež sakarīgs skaitlis
    return -1
End
Tas ko vēlējos tabūt- sarakstu ar "TODO:" (darāmajiem darbiem). Un lūk:

Ziņojumos varu redzēt uzdevumus, ko esmu piefiksējis "vēlākai darīšanai".
Ierobežojumi būtu tādi, ka "TODO:" jābūt bez tukšumiem un katram darāmajam darbam atbilst viena rinda. Skripts "saplīstu", ja vienā procedūrā būtu pārmēru liels darāmo darbu saraksts (rekursīva vaicājuma dēļ).. Protams, jābūt tiesībām uz attiecīgajiem datu bāzes objektiem un tie nevar būt šifrēti.

Skripti
Skripti ir veidoti lai strādātu uz SQL Server 2008. Vecākām SQL Server versijām būtu jāizdara mazi labojumi. (starp citu, usp_PrintToDoList ir praktiski nokopēts kods no CV lai iegūtu DB objekta izveides skriptu)

Create Function dbo.fn_ToDoList(@x nvarchar(max))
Returns Table
With Encryption
As
Return
(
    WITH Saraksts
    AS
    (
        SELECT
            0 AS Level,
            Substring(@x,
                CharIndex('TODO:', @x, 1) +
                CharIndex(CHAR(13), Substring(@x, CharIndex('TODO:', @x, 1), LEN(@x))),
                LEN(@x)) atlikums,
            Substring(@x,
                CharIndex('TODO:', @x, 1),
                Len(CharIndex(CHAR(13), Substring(@x, CharIndex('TODO:', @x, 1), LEN(@x)))) +
                    CharIndex(CHAR(13), Substring(@x, CharIndex('TODO:', @x, 1), LEN(@x))) - 1) todo       
        UNION ALL
        SELECT
            Level + 1,
            Substring(atlikums,
                CharIndex('TODO:', atlikums, 1) +
                CharIndex(CHAR(13), Substring(atlikums, CharIndex('TODO:', atlikums, 1), LEN(atlikums))),
                LEN(atlikums)) atlikums,
            Substring(atlikums,
                CharIndex('TODO:', atlikums, 1),
                Len(CharIndex(CHAR(13), Substring(atlikums, CharIndex('TODO:', atlikums, 1), LEN(atlikums)))) +
                    CharIndex(CHAR(13), Substring(atlikums, CharIndex('TODO:', atlikums, 1), LEN(atlikums))) - 1) todo   
        FROM Saraksts
        Where CharIndex('TODO:', atlikums, 1)  > 1
    )
    Select todo Daramais
    From Saraksts
)
Go
Create Procedure usp_PrintToDoList
With Encryption
As
Begin
    Set NoCount ON;
    declare @obj sysname
    declare @daramais nvarchar(max)
    declare @prev nvarchar(max)= '';
    declare cur cursor for
        select object_name(c.object_id) objekts, td.Daramais
        from sys.sql_modules c
            cross apply dbo.fn_ToDoList(c.definition) td
        where definition like '%TODO:%'

    open cur
    fetch next from cur into @obj, @daramais
    while @@fetch_status = 0
    Begin
        if(@prev != @obj)
        Begin
            print ''
            print 'Objekts: ' + @obj
            Set @prev = @obj
        End;
        print '   ' + @daramais
        fetch next from cur into @obj, @daramais
    End
    close cur
    deallocate cur
End

Nav komentāru:

Komentāra publicēšana