jueves, 9 de diciembre de 2010

Installing MongoDb as a service in Windows 7

Hi!

MongoDb is no-sql database. Their site is http://www.mongodb.org where you can find more information. First we need to download the mongodb from http://www.mongodb.org/downloads. I am using the version for Windows 64.

We can now unzip the content in the folder we want, for example in C:. Inside that folder, we need to create a folder named "Data" and a folder named "Logs" (Data folder is required, but Logs folder not, however, we will use it in this post).

We create a file named log.txt inside the Logs folder.

Now, let's start the database. We open a command-line (with administrative rights) and we go where we have placed our MongoDb folder. Inside the 'bin' folder, we have the executables. Let's now install the mongodb as a windows service.

To do that, we need to execute the next command:


mongod --bind_ip 127.0.0.1 --logpath c:\mongo\logs\log.txt 
--logappend --dbpath c:\mongo\data --directoryperdb --install

This will install mongodb as a windows service.  It is important to create the log.txt file before, in order to avoid errors. Finally we can check that everything went ok by accesing the url: 
It must show the MongoDb server page. That's all ;).

jueves, 30 de septiembre de 2010

Implementing a ChildWindow with MVVM in Silverlight (with DialogResult)

Hi! It is often asked which is the correct way to implement a childWindow and handle the DialogResult using the MVVM pattern. I've seen different approaches and I know that are several solutions to this, keeping the fundamentals of MVVM untouched. Well, this is my approach, that I've implemented in a couple of projects.

The main idea, is to use a view model that will handle the ChildWindow.xaml itself, and this view model will implement an interface. This way, in our view models where we want to use this child window, we will be referencing to an object of the type of the interface, making it mock-able and testeable. Let's take a look at the code.

First, we have the Child window, basically, the Xaml won't suffer any changes, but we could implement some logic in the code behind. This is ok (I guess) from the perspective of MVVM, because we are not putting there anything we want to test (I don't see to much utility in testing if the ok button works ;) ) and this code belongs to the child window only. This way, we can make a generic child window, and have in the code behind methods to change the icon, or the text in the ok/cancel buttons.

Now, lets create our interface, to ensure the testeability of our app.


   public interface IDialogWindowViewModel
    {
        
        void ShowConfirmWindow(string message, string title, Action dialogResultAction);
        void ShowMessageWindow(string message, string title, DialogTypes dialogType);
        void ShowConfirmWindow(string message, string title, string acceptButtonText, string cancelButtonText,
                               Action dialogResultAction);
        void ShowValidationResultsWindow(string title, List validationResult);


        void Close();
        DialogTypes DialogType { get; set; }
        bool DialogResult { get; set; }
        string Message { get; set; }
        string Title { get; set; }
        string AcceptButtonText { get; set; }
        string CancelButtonText { get; set; }
    }

I have this. As your needs change, you can put more methods/fields, but this is one example of how I did it. Then, we have the ViewModel that will implement that interface, and that actually will show the ChildWindow.


   public void ShowMessageWindow(string message, string title, DialogTypes dialogType)
        {
            _dialogChildWindow = new DialogChildWindow();
            _dialogChildWindow.DataContext = this;
            Message = message;
            Title = title;
            AcceptButtonText = "Aceptar";
            DialogType = dialogType;
            _dialogChildWindow.ChangeIcon(dialogType);
            _dialogChildWindow.Show();
        }


        public void ShowValidationResultsWindow(string title, List validationResults)
        {
            _dialogChildWindow = new DialogChildWindow();
            _dialogChildWindow.DataContext = this;
            Title = title;
            AcceptButtonText = "Aceptar";
            DialogType = DialogTypes.ErrorDialog;
            _dialogChildWindow.ChangeIcon(DialogType);
            _dialogChildWindow.ValidationSummaryMode(validationResults);
            _dialogChildWindow.Show();
        }


        public void ShowConfirmWindow(string message, string title, Action dialogResultAction)
        {
            _dialogChildWindow = new DialogChildWindow();
            _dialogChildWindow.DataContext = this;
            Message = message;
            Title = title;
            AcceptButtonText = "Aceptar";
            CancelButtonText = "Cancelar";
            DialogType = DialogTypes.ConfirmDialog;
            _dialogChildWindow.Closing += OnClosedDialogChildWindow;
            _dialogClosedAction = dialogResultAction;
            _dialogChildWindow.ChangeIcon(DialogTypes.ConfirmDialog);
            _dialogChildWindow.Show();
        }


        public void ShowConfirmWindow(string message, string title, string acceptButtonText, string cancelButtonText, Action dialogResultAction)
        {
            _dialogChildWindow = new DialogChildWindow();
            _dialogChildWindow.DataContext = this;
            Message = message;
            Title = title;
            AcceptButtonText = acceptButtonText;
            CancelButtonText = cancelButtonText;
            DialogType = DialogTypes.ConfirmDialog;
            _dialogChildWindow.Closing += OnClosedDialogChildWindow;
            _dialogClosedAction = dialogResultAction;
            _dialogChildWindow.ChangeIcon(DialogTypes.ConfirmDialog);
            _dialogChildWindow.Show();
        }


        private void OnClosedDialogChildWindow(object sender, EventArgs e)
        {
            var childWindow = sender as DialogChildWindow;
            if (childWindow != null)
            {
                if (childWindow.DialogResult.HasValue)
                    DialogResult = childWindow.DialogResult.Value;
            }
            _dialogChildWindow.Closing -= OnClosedDialogChildWindow;
            //_dialogChildWindow = null;
            _dialogClosedAction.Invoke(DialogResult);
        }


        public void Close()
        {
            if (_dialogChildWindow != null)
            {
                _dialogChildWindow.Close();
            }
        }

Then finally, we use this view model in another view model where we want to display the child window, here is an example of how it can be used.

We have the ViewModel instance:

 public IDialogWindowViewModel DialogWindowViewModel { get; set; }

and then we can safely call


 DialogWindowViewModel.ShowConfirmWindow(
                    string.Format("¿Do you want to delete item {0}?", SelectedItem.Id),
                    "Delete confirmation",
                    OnConfirmWindowClosed);

and the callback: OnConfirmWindowClosed, is something like

 private void OnConfirmWindowClosed(bool dialogResult)
        {
            if (dialogResult && SelectedItem != null)
            {
                SubmitOperationType = SubmitOperationType.Delete;
                _context.Clientes.Remove(SelectedItem);
                SubmitOperation so = null;
                so = _context.SubmitChanges(OnSubmitedChangesCompleted, so);
            }
        }

So we don't need to have multiple subscriptions. When we want to test our viewmodels, we'll just mock the method with another class implementing the interface, and everything will be fine :)

That is all. As I said, this is just one way of doing this, it has worked for me very well, and I think I am not breaking any patterns. You are welcome to make suggestions, and maybe show how you handle the child windows under MVVM. Hope that helps, and happy coding!

miércoles, 20 de mayo de 2009

Script para limpiar conexiones inactivas en oracle

Cuando se usa alguna de las versiones gratuitas de oracle, solo es posible mantener cierto número de conexiones abiertas en determinado momento, por lo que es necesario, acabar con conexiones que no se estén utilizando. Aunque desde el código de la aplicación se puede hacer, existen ocasiones en las cuales, por algún motivo u otro, se quedan abiertas y es necesario cerrarlas. Para ver las conexiones registradas por Oracle, podemos ejecutar el siguiente comando:

SELECT * FROM SYS.V_$SESSION WHERE STATUS = 'INACTIVE' AND SCHEMANAME<>'SYS'

Con la condición, no queremos que nos muestre las conexiones al esquema SYS, ya que son las usadas por oracle. Nos mostrará las conexiones inactiva, podemos cambiar el la condición del campo STATUS a 'ACTIVE', 'INACTIVE' o 'KILLED'. Si quitamos esa condición nos mostrará todas las conexiones registradas en ese momento.

Al realizar la consulta, existen ciertos campos a los cuales presenta valiosa información, el primero es el campo llamado LAST_CALL_ET, el cual muestra el tiempo en segudos desde la última vez que la conexión "hizo" algo. A mayor valor, más tiempo ha estado de ociosa. La otra columna a la que hay que prestarle atención es WAIT_CLASS, que puede presentar varios valores, siendo IDLE es el nos convendría eliminar.

Con base a esta información podemos eliminar (kill) aquellas sesiones que estén inactivas, tengan un LAST_CALL_ET alto, y su WAIT_CLASS sea IDLE. Para eliminar (kill) una conexión, utilizamos el siguiente comando:

ALTER SYSTEM KILL SESSION '65,327'

Donde el primer número (67) indica la SID de la conexion, y el segundo (327) el SERIAL#. Adicionalmente, se le puede añadir la palabra INMEDIATE al final de la instrucción para ejecutar la eliminación de manera instantanea.

Por último es posible que se desee borrar de manera automática todas las conexiones que poseaan dichas características, incluso de manera periódica. Para ello es recomendable crear un script que lo haga por nosotros. Cabe resaltar, que en caso de que sea frecuente que nos pase el problema con las conexiones, lo más correcto es buscar la causa, ya sea por cuestiones de programación o de la red. Pero bueno, para hacer el borrado a la mala, podemos usar el siguiente script:

BEGIN

FOR R IN (SELECT SID, SERIAL# FROM SYS.V_$SESSION WHERE STATUS = 'INACTIVE' AND SCHEMANAME<>'SYS' )

LOOP
execute IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' ||
R:SID || ',' || R.SERIAL# || '''';
END LOOP;

END;