Tuesday, March 15, 2016

Adding Artists to the Fan's List

I have made a method that can be included in the service to add artists the fan has selected to the fanArtist table.The code is commented to indicate what is going on.


 public int AddFanArtist( int fanKey, string artistName)
    {
        /*********************************
         * This method will add an artist to the artistFan
         * table. First we have to find the fan
         * and then the particular artist
         * Then we add the artist to the Fan's list
         * of artists to follow
         * **********************************/
        int result = 1;

        //get the fan. the key can come from their login
        Fan myFan = (from f in se.Fans
                     where f.FanKey == fanKey
                     select f).First();

        //get the artist by name
        Artist myArtist = (from a in se.Artists
                           where a.ArtistName.Equals(artistName)
                           select a).First();

        //add the artist to the fan;'s collection of artists
        myFan.Artists.Add(myArtist);

        //save the changes
        se.SaveChanges();

        return result;
    }
}

I also made a client method to show how you could use this. I used a CheckBoxList to select the artists from. Here is a picture of that on the web form

Obviously this could be made to look better. Here is the asp source code for the page


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p>Select your artists and click enter to add them</p>
        <asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatColumns="3"></asp:CheckBoxList>
        <asp:Button ID="Button1" runat="server" Text="Add Artists" OnClick="Button1_Click" />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    </div>
    </form>
</body>
</html>


Here is the code behind


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
    ServiceReference1.FanArtistServiceClient sc = new ServiceReference1.FanArtistServiceClient();
    protected void Page_Load(object sender, EventArgs e)
    {
        //I hard coded the key in so I didn't have to do the login 
        //for this example
        Session["key"] = 2;
        if (!IsPostBack)
            PopulateArtists();
        
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        AddArtists();
    }

    protected void PopulateArtists()
    {
        //this method populates the CheckboxList
        //with artist names
        string[] artists = sc.GetArtist();
        CheckBoxList1.DataSource = artists;
        CheckBoxList1.DataBind();
    }

    protected void AddArtists()
    {
        //get the fan's key
        int key = (int)Session["key"];

        //loop through the checkboxList
        //to see what's checked
        foreach(ListItem i in CheckBoxList1.Items)
        {
            //if it is checked call the service method to add
            //it to the database
            if(i.Selected)
            {
                int x = sc.AddFanArtist(key, i.Text);
            }
        }
        Label1.Text = "Artist have been added";
        CheckBoxList1.Items.Clear();
    }
}

The next thing to do will be to make a query of all the artists and their shows for a particular fan. Here is my first take on that method. It works but could be made more elegant perhaps. This method also goes in the service.


 public List<ShowInfo> GetShowsForFanArtists(int fanKey)
    {
        //get the fan
        Fan myFan = (from f in se.Fans
                     where f.FanKey == fanKey
                     select f).First();

        List<ShowInfo> shows = new List<ShowInfo>();

        //this loop within a loop is very inefficient
         foreach(Artist a in myFan.Artists)
         {
             //get all the shows for the fan
             var shws = from s in se.Shows
                        from sd in s.ShowDetails
                        where sd.ArtistKey == a.ArtistKey
                        select new
                        {
                            s.ShowName,
                            s.ShowTime,
                            s.ShowDate,
                            s.ShowTicketInfo,
                            s.Venue.VenueName,
                            sd.Artist.ArtistName
                        };

             //loop through the shows and write them to 
             //ShowInfo objects then add those objects
             //to the list
             foreach(var sh in shws)
             {
                 ShowInfo info = new ShowInfo();
                 info.ShowName = sh.ShowName;
                 info.ShowDate = sh.ShowDate.ToString();
                 info.ShowTime = sh.ShowTime.ToString();
                 info.TicketInfo = sh.ShowTicketInfo;
                 info.VenueName = sh.VenueName;
                 info.ArtistName = sh.ArtistName;

                 shows.Add(info);
             }
             
             
         }
         return shows;
                  
    }

Thursday, March 10, 2016

XML in SQL Server

--xml
use CommunityAssist

--raw is the simplest way to take tabular data and turn it into XML
--below are variations of the raw
Select PersonLastName, PersonFirstName,
PersonUserName
 From Person
For xml raw

Select PersonLastName, PersonFirstName,
PersonUserName
 From Person
For xml raw, elements 

Select PersonLastName, PersonFirstName,
PersonUserName
 From Person
For xml raw, elements, root('people')



Select PersonLastName, PersonFirstName,
PersonUserName
 From Person
For xml raw('person'), elements, root('people')

--xml auto lets you create deeper Hierachies
--the query below groups all the grants of the same
--kind together
Select ServiceName, GrantKey, GrantNeedExplanation, GrantAmount
From CommunityService [Service]
inner Join ServiceGrant Grants
on [Service].ServiceKey = Grants.ServiceKey
order by Grants.ServiceKey
For XML auto, elements, root('root')

Select * From GrantReview

--this is a very simple example of XQuery, a language
--you can use to query XML documents
Select GrantReviewDate, GrantKey, 
GrantReviewNote.query('declare namespace mn="http://www.communityassist.org/reviewnotes"; 
//mn:reviewnote/mn:comment') as Attending
From GrantReview
Where GrantKey =40

--a schema collection stores an XML Schema.
--an xml schema is an xml document that describes
--the structure of another xml document
--a schema collection can be used to enforce the 
--structure of xml documents stored in the database
Create xml Schema Collection DonorNotesSchemaCollection
As
'<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.communityassist.org/donornote" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="donornote">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="heading">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="title" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="body">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs="unbounded" name="note" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>'

--creating a table with an xml column
--the xml columns is set to be validated by the schema
--in our schema collection. This insures that it has
--a consistent structure
Create table DonorReview
(
    DonorReviewKey int identity(1,1) primary key,
 DonationKey int foreign key references Donation(DonationKey),
 DonorReviewDate Date Default GetDate(),
 DonorNote xml(DonorNotesSchemaCollection)
)

Insert into DonorReview(DonationKey, DonorNote)
Values(4
, '<?xml version="1.0" encoding="utf-8"?>
<donornote xmlns="http://www.communityassist.org/donornote">
  <heading>
    <title>Big Donor</title>
  </heading>
  <body>
  <note>
    This donor just gave a huge donation
  </note>
  <note>
    We should spam them for more
  </note>
    </body>
</donornote>')

Select * from DonorReview

Tuesday, March 8, 2016

Administrative commands

--logins permissions
--authentication, authorization
--Create a sql Server login
Create login Alberts with password='Pass'

Use CommunityAssist
--add a user in communityAssist mapped to that login 
Create user Alberts for Login Alberts

--create a new role
Create Role EmployeeRole

--Grant permissions on objects to the role
Grant Select on CommunityService to EmployeeRole
Grant Select, Update on Person to EmployeeRole
Grant Select, Update, Insert on ServiceGrant to EmployeeRole
Grant Select on BusinessRules to EmployeeRole

--add the user to the role
exec sp_addrolemember 'EmployeeRole', 'Alberts'

--does exactly the same as the above
Alter role EmployeeRole Add member Alberts

Select * from sys.syslogins

use CommunityAssist
Select * from Person

--schema. A schema is a collection of related objects
go
--create a scheam
Create schema ClientSchema
Go
--add a view to the schema. Note the SchemaName.ObjectName
Create view ClientSchema.vw_Grants
As
Select GrantDate, GrantAmount, PersonKey,
GrantNeedExplanation
From ServiceGrant
go
Create view ClientSchema.Vw_Services
As
Select ServiceName, ServiceDescription, ServiceMaximum, ServiceLifetimeMaximum
From CommunityService
go
--create another role
Create role NewClientRole

--add permisions on the schema to the role
Grant Select on Schema::ClientSchema to NewClientRole

--new login
Create login Larry with password='Pass'
--new user with a default schema
Create user LarryUser for Login Larry with default_schema=ClientSchema
go
--Add user to role
Alter role NewClientRole Add member LarryUser

/*****************
backups and restores
*******************/
--a full backup
Backup Database CommunityAssist to disk ='C:\Backups\CommunityAssist.bak'
--a differential backup
Backup Database CommunityAssist to disk ='C:\Backups\CommunityAssist2.bak'
with Differential
--restore. Must restore the full then the differentials, then the log if backed up
use Master
Restore Database CommunityAssist from disk='C:\Backups\CommunityAssist.bak'
with norecovery
Restore Database CommunityAssist from Disk='C:\Backups\CommunityAssist2.bak'
with recovery