Thursday, December 13, 2012

SQL 2000 Restore with Multiple .trn files

My previous blog post showed how to script a restore for SQL Server 2005 and above.  Below is a modified script which works on SQL Server 2000.  Basically i had to use temp tables instead of dynamic variables and I had to deal with SQL Server 2000's wacky backup file naming convention.

SQL:


USE Master;
GO
SET NOCOUNT ON
-- 1 - Variable declaration
DECLARE @dbName sysname
DECLARE @backupPath NVARCHAR(500)
DECLARE @MDFLDFPath NVARCHAR(500)
DECLARE @cmd NVARCHAR(500)
--DECLARE @fileList TABLE (backupFile NVARCHAR(255))
DECLARE @lastFullBackup NVARCHAR(500)
DECLARE @lastDiffBackup NVARCHAR(500)
DECLARE @backupFile NVARCHAR(500)

CREATE TABLE #fileList (backupFile NVARCHAR(255))

-- 2 - Initialize variables
-- Database Container Name
SET @dbName = 'ProgramPlan'

-- .BAK & .TRN Directory
SET @backupPath = N'C:\backup\sql\ProgramPlan\'

-- Final MDF/LDF Directory.
-- ** Directory must exists prior to running script**
SET @MDFLDFPath = N'C:\Program Files\Microsoft SQL Server\MSSQL\Data\'


-- 3 - get list of files
SET @cmd = 'DIR /b ' + @backupPath
INSERT INTO #fileList(backupFile)
EXEC xp_cmdshell @cmd

-- 4a - Find latest full backup
SELECT @lastFullBackup = MAX(backupFile)
FROM #fileList
WHERE backupFile LIKE '%.BAK'
   AND backupFile LIKE @dbName + '%'

-- 4b - Get the names of the MDF/LDF files from the backup
DECLARE @LogicalFileNameMDF NVARCHAR(128)
DECLARE @LogicalFileNameLDF NVARCHAR(128)

Create TABLE #fileListTable
(
    LogicalName          nvarchar(128),
    PhysicalName         nvarchar(260),
    [Type]               char(1),
    FileGroupName        nvarchar(128),
    Size                 numeric(20,0),
    MaxSize              numeric(20,0),
   
)
INSERT INTO #fileListTable EXEC('restore filelistonly from disk = ''' + @backupPath + @lastFullBackup + '''')

SELECT @LogicalFileNameMDF = LogicalName
FROM #fileListTable
WHERE TYPE = 'D'

SELECT @LogicalFileNameLDF = LogicalName
FROM #fileListTable
WHERE TYPE = 'L'

SET @cmd = 'RESTORE DATABASE ' + @dbName + ' FROM DISK = '''
   + @backupPath + @lastFullBackup + ''' WITH MOVE '''
   + @LogicalFileNameMDF +  ''' TO ''' + @MDFLDFPath + @dbName + '.MDF'', MOVE '''
   + @LogicalFileNameLDF + ''' TO ''' + @MDFLDFPath + @dbName + '.LDF'', NORECOVERY , REPLACE'
PRINT @cmd

-- 4 - Find latest diff backup
SELECT @lastDiffBackup = MAX(backupFile)
FROM #fileList
WHERE backupFile LIKE '%.DIF'
   AND backupFile LIKE @dbName + '%'
   AND RIGHT(backupFile,12) > RIGHT(@lastFullBackup,12)
-- check to make sure there is a diff backup
IF @lastDiffBackup IS NOT NULL
BEGIN
   SET @cmd = 'RESTORE DATABASE ' + @dbName + ' FROM DISK = '''
       + @backupPath + @lastDiffBackup + ''' WITH NORECOVERY'
   PRINT @cmd
   SET @lastFullBackup = @lastDiffBackup
END
-- 5 - check for log backups
DECLARE backupFiles CURSOR FOR
   SELECT backupFile
   FROM #fileList
   WHERE backupFile LIKE '%.TRN'
   AND backupFile LIKE @dbName + '%'
   AND RIGHT(backupFile,12) > RIGHT(@lastFullBackup,12)
OPEN backupFiles
-- Loop through all the files for the database
FETCH NEXT FROM backupFiles INTO @backupFile
WHILE @@FETCH_STATUS = 0
BEGIN
   SET @cmd = 'RESTORE LOG ' + @dbName + ' FROM DISK = '''
       + @backupPath + @backupFile + ''' WITH NORECOVERY'
   PRINT @cmd
   FETCH NEXT FROM backupFiles INTO @backupFile
END
CLOSE backupFiles
DEALLOCATE backupFiles
-- 6 - put database in a useable state
SET @cmd = 'RESTORE DATABASE ' + @dbName + ' WITH RECOVERY'
PRINT @cmd

drop table #fileList
drop table #fileListTable

Wednesday, December 12, 2012

SQL 2005, 2008, 2008R2, 2012 Database Restore with multiple .trn files

I was recently tasked with creating a procedure for restoring a MSSQL databases that can have up to 47 trn files.

The scenario: A full database backup happens each night with transaction backups happening every 30 mins after that.  The SQL Server Management Studio interface allows you to restore the files but you have to do it one at a time. When you have 6 databases with 6 full backups and up to 282 trn files, doing things one at a time is unacceptable.  In the end i created the following SQL Script:

** NOTE: This only works on SQL 2005 and above because of the naming defaults imposed by SQL 2000.

SQL 1 - turn on xp_cmdshell


-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO

SQL 2 - Restore SQL Databases

USE Master;
GO
SET NOCOUNT ON
-- 1 - Variable declaration
DECLARE @dbName sysname
DECLARE @backupPath NVARCHAR(500)
DECLARE @MDFLDFPath NVARCHAR(500)
DECLARE @cmd NVARCHAR(500)
DECLARE @fileList TABLE (backupFile NVARCHAR(255))
DECLARE @lastFullBackup NVARCHAR(500)
DECLARE @lastDiffBackup NVARCHAR(500)
DECLARE @backupFile NVARCHAR(500)

-- 2 - Initialize variables
-- Database Container Name
SET @dbName = 'DATABASE'

-- .BAK & .TRN Directory
SET @backupPath = N'C:\backup\DATABASE\'

-- Final MDF/LDF Directory.
-- ** Directory must exists prior to running script**
SET @MDFLDFPath = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\'


-- 3 - get list of files
SET @cmd = 'DIR /b ' + @backupPath
INSERT INTO @fileList(backupFile)
EXEC master.sys.xp_cmdshell @cmd

-- 4a - Find latest full backup
SELECT @lastFullBackup = MAX(backupFile)
FROM @fileList
WHERE backupFile LIKE '%.BAK'
   AND backupFile LIKE @dbName + '%'

-- 4b - Get the names of the MDF/LDF files from the backup
DECLARE @LogicalFileNameMDF NVARCHAR(128)
DECLARE @LogicalFileNameLDF NVARCHAR(128)

declare @fileListTable table
(
    LogicalName          nvarchar(128),
    PhysicalName         nvarchar(260),
    [Type]               char(1),
    FileGroupName        nvarchar(128),
    Size                 numeric(20,0),
    MaxSize              numeric(20,0),
    FileID               bigint,
    CreateLSN            numeric(25,0),
    DropLSN              numeric(25,0),
    UniqueID             uniqueidentifier,
    ReadOnlyLSN          numeric(25,0),
    ReadWriteLSN         numeric(25,0),
    BackupSizeInBytes    bigint,
    SourceBlockSize      int,
    FileGroupID          int,
    LogGroupGUID         uniqueidentifier,
    DifferentialBaseLSN  numeric(25,0),
    DifferentialBaseGUID uniqueidentifier,
    IsReadOnl            bit,
    IsPresent            bit,
    TDEThumbprint        varbinary(32)
)
INSERT INTO @fileListTable EXEC('restore filelistonly from disk = ''' + @backupPath + @lastFullBackup + '''')

SELECT @LogicalFileNameMDF = LogicalName
FROM @fileListTable
WHERE TYPE = 'D'

SELECT @LogicalFileNameLDF = LogicalName
FROM @fileListTable
WHERE TYPE = 'L'

SET @cmd = 'RESTORE DATABASE ' + @dbName + ' FROM DISK = '''
   + @backupPath + @lastFullBackup + ''' WITH MOVE '''
   + @LogicalFileNameMDF +  ''' TO ''' + @MDFLDFPath + @dbName + '.MDF'', MOVE '''
   + @LogicalFileNameLDF + ''' TO ''' + @MDFLDFPath + @dbName + '.LDF'', NORECOVERY , REPLACE'
PRINT @cmd

-- 4 - Find latest diff backup
SELECT @lastDiffBackup = MAX(backupFile)
FROM @fileList
WHERE backupFile LIKE '%.DIF'
   AND backupFile LIKE @dbName + '%'
   AND backupFile > @lastFullBackup
-- check to make sure there is a diff backup
IF @lastDiffBackup IS NOT NULL
BEGIN
   SET @cmd = 'RESTORE DATABASE ' + @dbName + ' FROM DISK = '''
       + @backupPath + @lastDiffBackup + ''' WITH NORECOVERY'
   PRINT @cmd
   SET @lastFullBackup = @lastDiffBackup
END
-- 5 - check for log backups
DECLARE backupFiles CURSOR FOR
   SELECT backupFile
   FROM @fileList
   WHERE backupFile LIKE '%.TRN'
   AND backupFile LIKE @dbName + '%'
   AND backupFile > @lastFullBackup
OPEN backupFiles
-- Loop through all the files for the database
FETCH NEXT FROM backupFiles INTO @backupFile
WHILE @@FETCH_STATUS = 0
BEGIN
   SET @cmd = 'RESTORE LOG ' + @dbName + ' FROM DISK = '''
       + @backupPath + @backupFile + ''' WITH NORECOVERY'
   PRINT @cmd
   FETCH NEXT FROM backupFiles INTO @backupFile
END
CLOSE backupFiles
DEALLOCATE backupFiles
-- 6 - put database in a useable state
SET @cmd = 'RESTORE DATABASE ' + @dbName + ' WITH RECOVERY'
PRINT @cmd

Monday, December 3, 2012

Hackintosh (aka CustoMac)

A co-worker  of mine (Thanks Matt!) has gotten a Hackintosh (aka CustoMac) running on his Dell Precision laptop.  Though a little buggy, it is a great proof of concept.  He passed along a couple websites giving a step by step tutorial on how to create the hackintosh with a pre-screened hardware guide and how to multiboot a hackintosh.  Below are the sites:

Bootloader Guide for a multi-os install which includes OS X Lion:  http://racerrehabman.wordpress.com/2012/07/06/guide-to-installing-windows-7-windows-8-mac-os-x-lion-and-ubuntu-multi-boot/

Hackintosh hardware setup guide:  http://tonymacx86.blogspot.com/search/label/CustoMac

MySQL Database Size check


Found this gem online today and thought i would share.  It shows the size in MB per database container for a MySQL database.

SELECT table_schema "Data Base Name",
sum( data_length + index_length ) / 1024 /
1024 "Data Base Size in MB",
sum( data_free )/ 1024 / 1024 "Free Space in MB"
FROM information_schema.TABLES
GROUP BY table_schema ;

Monday, November 26, 2012

Windows 7 Mapped Network Drive Problems

I first had issues connected to a mapped drive so i thought i would remove the mapping and reconnect it.  Then i got an error saying "This network connection does not exist" which was confusing because it clearly existed.  After consulting the all mighty google i found the following forum post with a fixed that worked which i am reiterating below.



1 - Type gpedit.msc in the Start menu’s search box and then press Enter.
2 - Navigate to User Configuration, Administrative Templates, Windows Components, and then select Windows Explorer in the left column of the Group Policy editor.
3 - Double-click Remove “Map Network Drive” and “Disconnect Network Drive” in the Settings section of the Group Policy editor.
4 - Select Enable, Apply and then click OK to save the changes.
5 - Open a command prompt and type "gpupdate /force"
6 - Log off and back on

(optional Step 5 - Restart Computer)

Thursday, November 8, 2012

MS SQL Maintenance

For those of you, who like me, need to reindex your databases every once in a while.  Here is the SQL command to do so:


SET NOCOUNT ON
GO

--Set the fillfactor
DECLARE @FillFactor TINYINT
SELECT @FillFactor=80

DECLARE @StartTime DATETIME
SELECT @StartTime=GETDATE()

if object_id('tempdb..#TablesToRebuildIndex') is not null
begin
drop table #TablesToRebuildIndex
end

DECLARE @NumTables VARCHAR(20)

SELECT
s.[Name] AS SchemaName,
t.[name] AS TableName,
SUM(p.rows) AS RowsInTable
INTO #TablesToRebuildIndex
FROM
sys.schemas s
LEFT JOIN sys.tables t
ON  s.schema_id = t.schema_id
LEFT JOIN sys.partitions p
ON  t.object_id = p.object_id
LEFT JOIN sys.allocation_units a
ON  p.partition_id = a.container_id
WHERE
p.index_id IN ( 0, 1 ) -- 0 heap table , 1 table with clustered index
AND p.rows IS NOT NULL
AND a.type = 1  -- row-data only , not LOB
GROUP BY
s.[Name],
t.[name]
SELECT @NumTables=@@ROWCOUNT

DECLARE RebuildIndex CURSOR FOR
SELECT
ROW_NUMBER() OVER (ORDER BY ttus.RowsInTable),
ttus.SchemaName,
ttus.TableName,
ttus.RowsInTable
FROM
#TablesToRebuildIndex AS ttus
ORDER BY
ttus.RowsInTable
OPEN RebuildIndex

DECLARE @TableNumber VARCHAR(20)
DECLARE @SchemaName NVARCHAR(128)
DECLARE @tableName NVARCHAR(128)
DECLARE @RowsInTable VARCHAR(20)
DECLARE @Statement NVARCHAR(300)
DECLARE @Status NVARCHAR(300)

FETCH NEXT FROM RebuildIndex INTO @TableNumber, @SchemaName, @tablename, @RowsInTable
WHILE ( @@FETCH_STATUS = 0 )
BEGIN
SET @Status='Table '+@TableNumber+' of '+@NumTables+': Rebuilding indexes on '+@SchemaName+'.'+@tablename + ' ('+@RowsInTable+' rows)'
RAISERROR (@Status, 0, 1) WITH NOWAIT  --RAISERROR used to immediately output status

SET @Statement = 'ALTER INDEX ALL ON ['+@SchemaName+'].['+@tablename +'] REBUILD WITH (FILLFACTOR = '+CONVERT(VARCHAR(3), @FillFactor)+' )'
EXEC sp_executesql @Statement

FETCH NEXT FROM RebuildIndex INTO @TableNumber, @SchemaName, @tablename, @RowsInTable
END

CLOSE RebuildIndex
DEALLOCATE RebuildIndex

drop table #TablesToRebuildIndex

Print 'Total Elapsed Time: '+CONVERT(VARCHAR(100), DATEDIFF(minute, @StartTime, GETDATE()))+' minutes'

GO

Tuesday, October 9, 2012

Chuck Norris Programming Jokes

Found this on a forum and through it was worth a post:


1. When Chuck Norris throws exceptions, it’s across the room.
2. All arrays Chuck Norris declares are of infinite size, because Chuck Norris knows no bounds.
3. Chuck Norris doesn’t have disk latency because the hard drive knows to hurry the heck up.
4. Chuck Norris writes code that optimizes itself.
5. Chuck Norris can’t test for equality because he has no equal.
6. Chuck Norris doesn’t need garbage collection because he doesn’t call .Dispose(), he calls .DropKick().
7. Chuck Norris’s first program was kill -9.
8. Chuck Norris burst the dot com bubble.
9. All browsers support the hex definitions #chuck and #norris for the colors black and blue.
10. MySpace actually isn’t your space, it’s Chuck’s (he just lets you use it).
11. Chuck Norris can write infinite recursion functions…and have them return.
12. Chuck Norris can solve the Towers of Hanoi in one move.
13. The only pattern Chuck Norris knows is God Object.
14. Chuck Norris finished World of Warcraft.
15. Project managers never ask Chuck Norris for estimations…ever.
16. Chuck Norris doesn’t use web standards as the web will conform to him.
17. “It works on my machine” always holds true for Chuck Norris.
18. Whiteboards are white because Chuck Norris scared them that way.
19. Chuck Norris doesn’t do Burn Down charts, he does Smack Down charts.
20. Chuck Norris can delete the Recycling Bin.
21. Chuck Norris’s beard can type 140 wpm.
22. Chuck Norris can unit test entire applications with a single assert.
23. Chuck Norris doesn’t bug hunt as that signifies a probability of failure, he goes bug killing.
24. Chuck Norris’s keyboard doesn’t have a Ctrl key because nothing controls Chuck Norris.
25. When Chuck Norris is web surfing websites get the message “Warning: Internet Explorer has deemed this user to be malicious or dangerous. Proceed?”.

Clay Shirky: How the Internet will (one day) transform government

This is a very good video i would recommend you watch.

Key concept: Cooperation without coordination.
http://www.ted.com/talks/clay_shirky_how_the_internet_will_one_day_transform_government.html

Thursday, September 13, 2012

Chocolatey: apt-get for windows

From the website:  Chocolatey NuGet is a Machine Package Manager, somewhat like apt-get, but built with windows in mind.

You can even build your own packages and submit them.  I really like the concept and can see myself using this technology as a free alternative to Microsoft System Center.

Website: http://chocolatey.org/
Github Page: https://github.com/chocolatey/chocolatey/wiki


Monday, September 10, 2012

AsteriskNOW 2.0.2 64-bit WAV to MP3

I recently revamped our PBX and installed AsteriskNOW 2.0.2 64-bit (http://www.asterisk.org/downloads).  There were lots of tutorials online dealing with setup and i was able to get the server and 15 Polycom 501 handsets setup in about 3 days.  Because i am often traveling or away from my desk for long periods of time I rely heavily on the voicemail to email feature. The problem was that the .wav files were not opening on my Android Phone. After doing some research i found out that the file was in an odd format (wav|gsm).  I had two options at this point:  I could either pay a couple bucks for an android app that would play this format or i would reconfigure my server to use another format like mp3 for free.

Being a self proclaimed saver and always looking for a challenge, I decided to search the internet for tutorials.  I found a great tutorial outlining the process found here:   http://pcaddicts.ca/rc/2011/06/26/asterisknow-freepbx-mp3-voicemail/.

As i started through the process i quickly realized that this tutorial was written for an x86 setup and not an x64 setup.  Below is the steps i used on my x64 CentOS 5.8 final AsteriskNOW 2.0.2 64-bit setup.

1) Login into your box

2) Goto your home directory
cd /home/

3) Download the lastest version of lame from here http://pkgs.repoforge.org/lame/
wget http://pkgs.repoforge.org/lame/lame-3.97-1.el5.rf.x86_64.rpm

4) install rpm
rpm -Uvh lame-3.97-1.el5.rf.x86_64.rpm

5) Create the following script as /usr/sbin/sendmp3voicemail.pl
nano /usr/sbin/sendmp3voicemail.pl
#!/usr/bin/perl
open(VOICEMAIL,"|/usr/sbin/sendmail -t");
open(LAMEDEC,"|/usr/bin/dos2unix|/usr/bin/base64 -di|/usr/bin/lame --quiet --preset voice - /var/spool/asterisk/tmp/vmout.$$.mp3");
open(VM,">/var/spool/asterisk/tmp/vmout.debug.txt"); 
my $inaudio = 0;
loop: while(<>){
  if(/^\.$/){
    last loop;
  }
  if(/^Content-Type: audio\/x-wav/i){
    $inaudio = 1;
  }
  if($inaudio){
    while(s/^(Content-.*)wav(.*)$/$1mp3$2/gi){}
    if(/^\n$/){
      iloop: while(<>){
        print LAMEDEC $_;
        if(/^\n$/){
          last iloop;
        }
      }
      close(LAMEDEC);
      print VOICEMAIL "\n";
      print VM "\n";
      open(B64,"/usr/bin/base64 /var/spool/asterisk/tmp/vmout.$$.mp3|");
      while(){
        print VOICEMAIL $_; 
 print VM $_; 
      }
      close(B64);
      print VOICEMAIL "\n";
      print VM "\n";
      $inaudio = 0;
    }
  }
  print VOICEMAIL $_;
  print VM $_;
}
print VOICEMAIL "\.";
print VM "\.";
close(VOICEMAIL);
close(VM);

#CLEAN UP THE TEMP FILES CREATED
#This has to be done in a separate cron type job
#because unlinking at the end of this script is too fast,
#the message has not even gotten piped to send mail yet


6) Make the script executable
chmod 775 /usr/sbin/sendmp3voicemail.pl

7)Change default voicemail format to uncompressed WAV (which will be converted to MP3) and set mailcmd script.
FreePBX -> Voicemail Admin -> Settings

Changes:

format= wav
mailcmd= /usr/sbin/sendmp3voicemail.pl


8) Restart Asterisk and test
service asterisk restart

Thursday, September 6, 2012

Thoughts about article "Time to Give Java the Boot?"

I started reading an article titled "Time to Give Java the Boot?" found here:

http://www.pcworld.com/article/261843/time_to_give_java_the_boot.html

I almost stopped reading this article once they made the following statement: "The Mac operating system has been near-bulletproof to vulnerabilities...".

As most system admins know, the only reason that the Mac operating system has been "near-bulletproof" is because until recently they didn't have enough market share to matter to virus/malware authors.  Now that they do, this perception is changing.  Apple itself has had to remove statements like "It doesn't get PC viruses" from their website because it actually does get viruses... see http://www.pcmag.com/article2/0,2817,2406275,00.asp.

I am not an Apple hater.  I use my ipad almost daily but it is statements like this that make people complacent about their security and leave them vulnerable to attack. If technical writes at pcworld believe the apple marketing hype then i can only image what the general public must think.

As far as the point of the article, i agree that java is becoming less important for end users and i believe browser based technologies like HTML 5 will eventually replace java on the desktop but on the server JAVA and the JVM are here to stay.


Wednesday, August 22, 2012

uncommon.js

A good friend of mine named Mike Jeffery has created a new javascript tool called uncommon.js.  Currently  no other tool lets you build a script without having all of the dependencies at package time and so Mike created one for a project our company is working on.  If you need such a tool please check out https://github.com/mjeffery/uncommon.  This tool is still in alpha so be nice about bugs :)

More info:
Modern javascript libraries like Backbone and ember.js often require lower-level libraries that are very common, heavyweight, or use shared-state configuration. For example: underscore or jQuery. The developers want to provide a single, prebuilt script but won't, can't, or shouldn't include the necessary libraries. uncommon is an alternative to the complicated and/or project specific tools used for packaging these scripts without their runtime dependencies.

With uncommon you can write and organize your library or application as simple CommonJS modules and then compile them into a single script. uncommoncan import dependencies from the global scope and expose them as modules; allowing your code to depend on shared libraries or legacy scripts that may already be loaded on the page. 'uncommon' can also export your module as a global symbol so legacy or inline scripts can use it without any loaders or modification. Projects configured for use with 'uncommon' are compatible with other CommonJS runtimes and package managers (such as npm).



Tuesday, July 31, 2012

The Internet Map

http://internet-map.net

From the site:


The map of the Internet

Like any other map, The Internet map is a scheme displaying objects’ relative position; but unlike real maps (e.g. the map of the Earth) or virtual maps (e.g. the map of Mordor), the objects shown on it are not aligned on a surface. Mathematically speaking, The Internet map is a bi-dimensional presentation of links between websites on the Internet. Every site is a circle on the map, and its size is determined by website traffic, the larger the amount of traffic, the bigger the circle. Users’ switching between websites forms links, and the stronger the link, the closer the websites tend to arrange themselves to each other.

Tuesday, July 24, 2012

The Mythical Man-Month: Essays on Software Engineering

Over the past couple months i have been reading through the book The Mythical Man-Month by Fred Brooks.  It was originally written in 1975 but many of the concepts still apply today. I have been apart of projects which have fallen into some of the traps talked about in the book. Below are some quotes (some paraphrased) from the book (one or two from my experience) i think everyone in senior management should think about before starting a large scale software development project:


  1. Never build when you can buy
  2. The programming project converges more slowly the nearer one gets to the end - plan for it
  3. Good cooking takes time; some tasks cannot be hurried without spoiling the result
  4. All programmers are optimists and are typically bad estimators
  5. Men and months are not interchangeable (in my own words:  you can not take 9 women and make a baby in 1 month just like you can't double your programming staff and expect to cut the project in half)
  6. Estimating is hard due to the fact that that programmers are building something that has never been built before.  If it has been built before then you should be buying it off the self...
  7. Because programmers are uncertain about our scheduling estimates, they often lack the courage to defend them stubbornly against management and customer pressure.
  8. Brooks's Law: Adding manpower to a late software project makes it later.
  9. Adding manpower to a software project increases the total effort necessary in three ways:  the work and disruption of re partitioning itself, training new people and added intercommunication.
  10. 1 good programmer is worth 10 mediocre ones


Monday, July 9, 2012

Ubuntu Linux - Removing files based on date

A little script to remove files based on date.
This command will remove anything older then 30 days:
find /data/server/log/ -mtime +30 -exec rm {} \;

This command will remove anything over 1 year:
find /data/server/log/ -mtime +360 -exec rm {} \;


Thursday, July 5, 2012

Office Communicator Server 2007 Simple Log - SQL

We currently use Office Communicator Server 2007 (OCS) and my boss asked me for a simple log of all the activity for the past month.  I thought an SQL Script would be easy to find on the internet but it wasn't so wrote my own and am posting it here:


OCS 2007 SQL - Simple Log:
SELECT MessageIdTime, uf.UserUri as [From], ut.UserUri as [To], m.Body
from LcsLog.dbo.Messages m
join LcsLog.dbo.Users uf on m.FromId = uf.UserId
join LcsLog.dbo.Users ut on m.ToId = ut.UserId
where 
m.MessageIdTime between '06/01/2012 00:00:00' AND '06/30/2012 23:59:59'

To strip out the HTML tags in Excel you start Excel's Replace (Edit/Replace or Ctrl+H) and put <*> (that is 3 characters, a less-than symbol, an asterisk, and a greater-than symbol) for your "Find what" condition and leave the "Replace with" field empty.

Wednesday, June 20, 2012

ODBC/DSN Adventures


I was having issues with the ODBC connections of a legacy classic asp project i was working on.


I received the error "the specified dsn contains an architecture mismatch between the driver and application".


Unfortunately the previous "developers" (i use this term loosely)  decided to use DSN connections instead of a real connection string like:
(oConn.Open = "Provider=SQLOLEDB; Data Source=SERVER; Initial Catalog=CAT; User Id=sa; Password=*************").


Because I am running a Win7 x64 machine i needed to use the x32 odbc driver and not the x64 one.  If you type ODBC into the start menu you get the x64 version whereas if you type c:\windows\sysWOW64\odbcad32.exe it will open the x32 version.  This also help when connecting a mysql server through ODBC to excel.

Monday, June 18, 2012

Understanding Malware

This is one of the best video's i have ever seen regarding windows internal processing and how to identify and kill malware. http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/SIA302

Monday, June 11, 2012

Monday, June 4, 2012

Installing Couchdb 1.2 on Ubuntu 12.04 server

Helpful links: http://cvee.github.com/blog/2011/11/28/configuring-couchdb-on-ubuntu/

1) install git
apt-get install git

2) make directory for source
mkdir /data/couchdb_source

3) put source files into directory
cd /data/couchdb_source
git clone http://git-wip-us.apache.org/repos/asf/couchdb.git

4) change branch to version you need. We will be checking out 1.2.0
cd /data/couchdb_source/couchdb
git checkout 1.2.0
5) Install dependencies needed to build couchdb
sudo apt-get -y install build-essential autoconf automake libtool erlang libicu-dev libmozjs-dev libcurl4-openssl-dev
6) Build the configure and make files
./bootstrap
./configure --prefix=/data/couchdb
make && sudo make install
7) Create a user account dedicated for CouchDB and update permissions
sudo adduser --system --home /data/couchdb/var/lib/couchdb --no-create-home --shell /bin/bash --group --gecos "CouchDB Administrator" couchdb
sudo chown -R couchdb:couchdb /data/couchdb
sudo chmod 0770 -R /data/couchdb
8) Update Admin pass
/data/couchdb/etc/couchdb/local.ini
Change:
[admins]
root = [PASS]
9) Make it so couchdb will startup automatically
sudo cp /data/couchdb/etc/init.d/couchdb /etc/init.d
sudo update-rc.d couchdb defaults
10) Update Couchdb Config settings
nano /data/couchdb/etc/couchdb/default.ini
a) set delayed_commits - false
b) set reduce_limit - false

 11) Open firewall
iptables -A INPUT -p tcp -d 0/0 -s 0/0 --dport 5984 -j ACCEPT
iptables -A INPUT -p tcp -d 0/0 -s 0/0 --dport 6984 -j ACCEPT

12) Start Couchdb
service couchdb start

Phoenix

I am resurrecting this tech blog for notes related to Azure Logic Apps with SAP.