Download MySQL at: http://dev.mysql.com/downloads/ (More Specific) & install the DMG
1. Open up Terminal
2. Add /usr/local/mysql/bin to PATH
- cd ~
- emacs .profile
- export PATH="$PATH:/usr/local/mysql/bin"
3. Restart Terminal
4. Create new user for login
- mysqladmin -u USERNAME -p -password PASSWORD
5. Log in to MySQL with new user created
- mysql --user=USERNAME --password=PASSWORD
You should be in MySQL now
SERVER: FSB vs. RAM
Taken from: http://www.directron.com/fsbguide.html
Front Side Bus (FSB) - The Front Side Bus is the most important bus to consider when you are talking about the performance of a computer. The FSB connects the processor (CPU) in your computer to the system memory. The faster the FSB is, the faster you can get data to your processor.
System clock - The actual speed of your FSB with out any enhancements (such as double pumping, or quad pumping) on it. An often-misunderstood property of the system clock is its effect on processor speed. You see, a thing called a "CPU Multiplier" determines the speed of a processor in MHz. If you take the CPU Multiplier and multiply it by the System Clock speed you get the speed of your processor.
DDR2 - DDR2 memory has a different approach to design at the chip level than DDR. The simplest way to understand how it works would be to think that at the low level it had two chips of half the stated memory speed working in tandem together to achieve the full speed stated. So for DDR2 400 it would be something like 2 chips of DDR200 working together to achieve the full 400 speed. Notice that I say "chips" not sticks of memory. All this happens on 1 stick of memory. In other words, when calculating in tandem in respect to the FSB, just divide the given speed by 2.
Example:
Assume my quad-core, quad-pumped FSB = 1066MHz.
This means my System Clock is 1066/4 = 266MHz.
My CPU is clocked at 1.6GHz = 266MHz * CPU MULTIPLIER.
This means my CPU MULTIPLIER must be 1600/266 = 6.
Now here are my options for DDR2:
(A) 533MHz/2 = 266MHz. This is an EXACT MATCH to my System Clock.
(B) 667MHz/2 = 333MHz. This is the next highest speed available.
(C) 800MHz/2 = 400MHz. This is pure overkill since the System Clock is capped at 266MHz.
In these stated cases, (B) is actually preferred. (A) is an exact match which means sometimes its lag can adversely affect the CPU bus speed. As stated, option (C) is overkill.
Front Side Bus (FSB) - The Front Side Bus is the most important bus to consider when you are talking about the performance of a computer. The FSB connects the processor (CPU) in your computer to the system memory. The faster the FSB is, the faster you can get data to your processor.
System clock - The actual speed of your FSB with out any enhancements (such as double pumping, or quad pumping) on it. An often-misunderstood property of the system clock is its effect on processor speed. You see, a thing called a "CPU Multiplier" determines the speed of a processor in MHz. If you take the CPU Multiplier and multiply it by the System Clock speed you get the speed of your processor.
DDR2 - DDR2 memory has a different approach to design at the chip level than DDR. The simplest way to understand how it works would be to think that at the low level it had two chips of half the stated memory speed working in tandem together to achieve the full speed stated. So for DDR2 400 it would be something like 2 chips of DDR200 working together to achieve the full 400 speed. Notice that I say "chips" not sticks of memory. All this happens on 1 stick of memory. In other words, when calculating in tandem in respect to the FSB, just divide the given speed by 2.
Example:
Assume my quad-core, quad-pumped FSB = 1066MHz.
This means my System Clock is 1066/4 = 266MHz.
My CPU is clocked at 1.6GHz = 266MHz * CPU MULTIPLIER.
This means my CPU MULTIPLIER must be 1600/266 = 6.
Now here are my options for DDR2:
(A) 533MHz/2 = 266MHz. This is an EXACT MATCH to my System Clock.
(B) 667MHz/2 = 333MHz. This is the next highest speed available.
(C) 800MHz/2 = 400MHz. This is pure overkill since the System Clock is capped at 266MHz.
In these stated cases, (B) is actually preferred. (A) is an exact match which means sometimes its lag can adversely affect the CPU bus speed. As stated, option (C) is overkill.
WEB: How to set up web-server w/ FiOS
Since Verizon blocks port 80, this is listed online as the only workaround. It entails targeting a different port (like 8015), and then using the Verizon FiOS router to re-route the request to the correct web server machine.
Furthermore, people used no-ip.com's dynamic dns service to automatically forward the url name requests like www.happy.com to www.happy.com:8015, thereby eliminating the ugliness of forcing your customers to specify the ports.
* Prior to following the steps in this guide to hosting your web server, make sure you read the Verizon ToS, which states the following:
You also may not exceed the bandwidth usage limitations that Verizon may establish from time to time for the Service, or use the Service to host any type of server. Violation of this section may result in bandwidth restrictions on your Service or suspension or termination of your Service.
That said, be careful and charging on :)
STEP 1: Goto URL http://192.168.1.1
STEP 2: By default, username = admin, password = password (or password1)

STEP 3: On the top navi-bar, select Firewall Settings

STEP 4: Click yes to proceed

STEP 5: Click on Port Forwarding on the left navi-bar

STEP 6: From that table list, click Add at the bottom

STEP 7: Fill out the following table...
STEP 7a: Networked Computer/Device = danny (actual device name works best, since IPs can be dynamic)

STEP 8: Add new protocol

STEP 9: WAN Connection Type: All Broadband Devices
STEP 10: Forward to Port: Specify - 80
STEP 11: When should this rule occur: Always
STEP 12: Click Apply to get out of the Edit Port Forwarding Rule page
STEP 13: Click Apply to get out of the Port Forwarding page
STEP 14: From an external computer, type http://YOUR.IP:8015/, should direct you to the web server.
Furthermore, people used no-ip.com's dynamic dns service to automatically forward the url name requests like www.happy.com to www.happy.com:8015, thereby eliminating the ugliness of forcing your customers to specify the ports.
* Prior to following the steps in this guide to hosting your web server, make sure you read the Verizon ToS, which states the following:
You also may not exceed the bandwidth usage limitations that Verizon may establish from time to time for the Service, or use the Service to host any type of server. Violation of this section may result in bandwidth restrictions on your Service or suspension or termination of your Service.
That said, be careful and charging on :)
STEP 1: Goto URL http://192.168.1.1
STEP 2: By default, username = admin, password = password (or password1)

STEP 3: On the top navi-bar, select Firewall Settings

STEP 4: Click yes to proceed

STEP 5: Click on Port Forwarding on the left navi-bar

STEP 6: From that table list, click Add at the bottom

STEP 7: Fill out the following table...
STEP 7a: Networked Computer/Device = danny (actual device name works best, since IPs can be dynamic)

STEP 8: Add new protocol

STEP 9: WAN Connection Type: All Broadband Devices
STEP 10: Forward to Port: Specify - 80
STEP 11: When should this rule occur: Always
STEP 12: Click Apply to get out of the Edit Port Forwarding Rule page
STEP 13: Click Apply to get out of the Port Forwarding page
STEP 14: From an external computer, type http://YOUR.IP:8015/, should direct you to the web server.
APACHE: Enabling Apache + PHP on OSX
Step 1. Menu Bar > Go > Go to Folder... > /private/etc/apache2
Step 2. Open httpd.conf with TextEditor
Step 3. Uncomment this line:
#LoadModule php5_module libexec/apache2/libphp5.so
Step 4. Save this file onto the desktop as "httpd.conf"
Step 5. Drag the "httpd.conf" file you just created into /private/etc/apache2
Step 6. Authenticate your privileges: enter your password
Step 7. Make a copy of /etc/php.ini.default onto your desktop
Step 8. Rename php.ini.default to php.ini (the copy on your desktop)
Step 9. Drag the "php.ini.default" file you just created into /private/etc
Step 10. Authenticate your privileges: enter your password
Step 11. Open System Preferences > Sharing > Web Sharing: ON (check this option)
To Test:
Step 12. Create info.php with the content:
Step 13. Save it to /Library/WebServer/Documents
Step 14. Goto http://localhost/info.php
To Publish using your HOME/Sites directory
Step 15. Create info.php with content:
Step 16. Save it to /Users/$MYNAME/Sites
Step 17. Goto http://$COMPUTERNAME.home/~$MYNAME/info.php
Step 2. Open httpd.conf with TextEditor
Step 3. Uncomment this line:
#LoadModule php5_module libexec/apache2/libphp5.so
Step 4. Save this file onto the desktop as "httpd.conf"
Step 5. Drag the "httpd.conf" file you just created into /private/etc/apache2
Step 6. Authenticate your privileges: enter your password
Step 7. Make a copy of /etc/php.ini.default onto your desktop
Step 8. Rename php.ini.default to php.ini (the copy on your desktop)
Step 9. Drag the "php.ini.default" file you just created into /private/etc
Step 10. Authenticate your privileges: enter your password
Step 11. Open System Preferences > Sharing > Web Sharing: ON (check this option)
To Test:
Step 12. Create info.php with the content:
Step 13. Save it to /Library/WebServer/Documents
Step 14. Goto http://localhost/info.php
To Publish using your HOME/Sites directory
Step 15. Create info.php with content:
Step 16. Save it to /Users/$MYNAME/Sites
Step 17. Goto http://$COMPUTERNAME.home/~$MYNAME/info.php
IPHONE: MySQL on iPhone
Before we go on, I'm going to assume you already know that the simplest way to achieve MySQL data connection is by writing a short scriptlet in PHP/JSP, etc. While simpler, it's security is somewhat problematic, since sniffers may be able to pick up the URL requests.
After hours of research I found what seems like the only solution: Cocoa-MySQL + MySQL C-API
According to this blog, all you seem to need is Cocoa-MySQL, but no matter what I tried, I just couldn't seem to get the binaries to link correctly. Not to mention, Apple has a pretty strict limitation on private frameworks, and this solution probably goes against one of their 20 NDAs.
This is where MySQL C-API comes in handy. I downloaded Mac OS X 10.5 (TAR package) for my x86 Intel system. Extract the zip and grab the /lib and /include folders and throw them into some local directory (NOT IN YOUR XCODEPROJ, see steps 4, 5 below).
From the Cocoa-MySQL site, download MCPKit_src_XXX.dmg, and grab the contents of /MCPFoundationKit and throw it into your XCODEPROJ. These are great wrapper classes that help facilitate the connection & query processes.
If you tried to build the app right now, you'd get errors stating missing headers and mysql_xxx_xxx functions. That's because we haven't set up the project settings yet.
1. In Xcode, goto Project > Edit Project Settings.
2. Select the Build tab.
3. Under Linking > Other Linking FLags, add the following flags: -lmysqlclient_r, -lmysqld, -lmysqlclient, -lm, -lz
4. Under Search Paths > Header Search Paths:
5. Under Search Paths > Library Search Paths:
6. Add #import "MCPKit_bundled.h" to the header of any class accessing MySQL
7. Edit MCPKit_bundled.h by changing all #import to #import "XXX.h"
Now you should be able to build, and use the sample code from the blog previously mentioned to directly connect to a remote MySQL server.
After hours of research I found what seems like the only solution: Cocoa-MySQL + MySQL C-API
According to this blog, all you seem to need is Cocoa-MySQL, but no matter what I tried, I just couldn't seem to get the binaries to link correctly. Not to mention, Apple has a pretty strict limitation on private frameworks, and this solution probably goes against one of their 20 NDAs.
This is where MySQL C-API comes in handy. I downloaded Mac OS X 10.5 (TAR package) for my x86 Intel system. Extract the zip and grab the /lib and /include folders and throw them into some local directory (NOT IN YOUR XCODEPROJ, see steps 4, 5 below).
From the Cocoa-MySQL site, download MCPKit_src_XXX.dmg, and grab the contents of /MCPFoundationKit and throw it into your XCODEPROJ. These are great wrapper classes that help facilitate the connection & query processes.
If you tried to build the app right now, you'd get errors stating missing headers and mysql_xxx_xxx functions. That's because we haven't set up the project settings yet.
1. In Xcode, goto Project > Edit Project Settings.
2. Select the Build tab.
3. Under Linking > Other Linking FLags, add the following flags: -lmysqlclient_r, -lmysqld, -lmysqlclient, -lm, -lz
4. Under Search Paths > Header Search Paths:
5. Under Search Paths > Library Search Paths:
7. Edit MCPKit_bundled.h by changing all #import
Now you should be able to build, and use the sample code from the blog previously mentioned to directly connect to a remote MySQL server.
IPHONE: IBAction and IBOutlet
Sometimes when all you need is a simple UI application that doesn't require too much customization or skinning, you can try building the application in Interface Builder.
Step 1: Create a New Project (Apple+Shift+N) > View-Based Application, name the application IBTest


Step 2: Edit the default IBTestViewController.h & .m files. Add the following lines in the appropriate places:
IBOutlet UIButton* button; IBOutlet UILabel* label; - (IBAction)userPressedButton:(id)sender;

Step 3: Open MainWindow.xib w/ Interface Builder
Step 4: Double-Click Test View Controller and a window will pop up

Step 5a: Add a View (from the library: APPLE+L) to Test View Controller
Step 5b: Add a Rounded Rect Button to the View you just added
Step 5c: Add a Label to the View you just added

Step 6: Link your UIButton & UILabel to the button and label you just added . You can do this by Apple+Right-Clicking the Rounded Rect Button & drag your mouse onto the Test View Controller

Step 7: Select userPressedButton in the popup

Done... your code is now hooked up through the interface builder. When users click the button, your userPressedButtons method will fire, as expected.
Step 1: Create a New Project (Apple+Shift+N) > View-Based Application, name the application IBTest


Step 2: Edit the default IBTestViewController.h & .m files

Step 3: Open MainWindow.xib w/ Interface Builder

Step 5b: Add a Rounded Rect Button to the View you just added
Step 5c: Add a Label to the View you just added


Step 7: Select userPressedButton in the popup

IPHONE: Removing the GLOSS from the app icon
Edit the Info.plist file...
UIPrerenderedIcon = true
In plain text:
UIPrerenderedIcon
UIPrerenderedIcon = true
In plain text:
IPHONE: Changing the Product Name
If your single source produces multiple 'products', ie. *.app's, it may be necessary to differentiate the 2 by designating the product names.
To create 2 products from 1 source:
- Create a new target by making a copy of the first.
- Modify this target by changing its Info.plist (by default will be Info Copy.plist)
- Modify its displayed name by changing its Infoplist.strings
- Optionally you can add a PREPROCCESSOR MACRO to differentiate the 2 targets (see previous post)
But when you compile the 2 targets, they always have the same .app name. This could be problematic for multiple reasons...
- If your bundle identifier is com.xxx.Application, your Product name should be 'Application'
- If you want to differentiate the 2 builds, it'd be easier if the 2 did not have the same app name
To do so:
- Highlight the Targets > Application 1
- Right click > Get Info
- Build tab
- Packaging > Product Name = New Application name
To create 2 products from 1 source:
- Create a new target by making a copy of the first.
- Modify this target by changing its Info.plist (by default will be Info Copy.plist)
- Modify its displayed name by changing its Infoplist.strings
- Optionally you can add a PREPROCCESSOR MACRO to differentiate the 2 targets (see previous post)
But when you compile the 2 targets, they always have the same .app name. This could be problematic for multiple reasons...
- If your bundle identifier is com.xxx.Application, your Product name should be 'Application'
- If you want to differentiate the 2 builds, it'd be easier if the 2 did not have the same app name
To do so:
- Highlight the Targets > Application 1
- Right click > Get Info
- Build tab
- Packaging > Product Name = New Application name
IPHONE: Environment Variables & #define directives
To use Configuration-defined #defines
Step 1: Right click on the project/target and select Get Info.
Step 2: Under the Build tab, select the Configuration you want to associate the #define with (ie. Debug/Release)
Step 3: Under User-Defined (Setting) all the way at the bottom, find a field that's called
GCC_PREPROCESSOR_DEFINITIONS
Step 4: If a field doesn't already exist, create it by clicking on the Gear on the bottom left & selecting Add User-Defined Setting.
Step 5: For the VALUE, input your #define variable. (ie. TEST_DEFINES)
Step 6: Now in code you can use
#ifdef TEST_DEFINES
... do something
#else
... do something
#endif
Step 1: Right click on the project/target and select Get Info.
Step 2: Under the Build tab, select the Configuration you want to associate the #define with (ie. Debug/Release)
Step 3: Under User-Defined (Setting) all the way at the bottom, find a field that's called
GCC_PREPROCESSOR_DEFINITIONS
Step 4: If a field doesn't already exist, create it by clicking on the Gear on the bottom left & selecting Add User-Defined Setting.
Step 5: For the VALUE, input your #define variable. (ie. TEST_DEFINES)
Step 6: Now in code you can use
#ifdef TEST_DEFINES
... do something
#else
... do something
#endif
Tomcat: Starting tomcat in Mac OSX
When http://localhost:8080 isn't working, you may want to try starting the tomcat server.
I'm going to assume that Tomcat was installed at /Library/Tomcat/apache-tomcat-6.0.18/
cd /Library/Tomcat/apache-tomcat-6.0.18/bin
./startup.sh
p.s. During setup, make sure CATALINA_HOME points to /Library/Tomcat/apache-tomcat-6.0.18. If it is not, edit your .profile file and redirect the CATALINA_HOME environment variable.
I'm going to assume that Tomcat was installed at /Library/Tomcat/apache-tomcat-6.0.18/
cd /Library/Tomcat/apache-tomcat-6.0.18/bin
./startup.sh
p.s. During setup, make sure CATALINA_HOME points to /Library/Tomcat/apache-tomcat-6.0.18. If it is not, edit your .profile file and redirect the CATALINA_HOME environment variable.
iPhone: Localization
Should have done my research before trying to do my own localization on the phone... the full article can be found here. Here are the basic steps to localizing your iphone application. Trust me, this is the way to do it...
Step 1: Create 2 directories called en.lproj (English) and it.lproj (Italian)
Step 2: Add new string file by going to File -> New File -> Other -> Strings File, name the file as "Localizable.strings" and place it in en.lproj.
Step 3: Repeat step 2, this time saving "Localizable.strings" inside it.lproj.
Step 4: Add the following lines to the strings files...
Step 5: To grab WelcomeKey you just do: NSLocalizedString(@"WelcomeKey", @"") like so:
That's all there is to it... Here are some of Apple's conventional language codes:
English: en
Japanese: ja
French: fr
Deutsch: de
Netherlands: nl
Italian: it
Spanish: es
Portugues: pt
Korean: ko
Simplified Chinese: zh-Hans
Traditional Chinese: zh-Hant
The full list can be accessed through the following call:
Step 1: Create 2 directories called en.lproj (English) and it.lproj (Italian)
Step 2: Add new string file by going to File -> New File -> Other -> Strings File, name the file as "Localizable.strings" and place it in en.lproj.
Step 3: Repeat step 2, this time saving "Localizable.strings" inside it.lproj.
Step 4: Add the following lines to the strings files...
"WelcomeKey" = "Welcome!!!"; // put into english version
"WelcomeKey" = "Benvenuto!!!";
// put into italian version
Step 5: To grab WelcomeKey you just do: NSLocalizedString(@"WelcomeKey", @"") like so:
NSLog(@"Welcome Text: %@", NSLocalizedString(@"WelcomeKey", @""));
That's all there is to it... Here are some of Apple's conventional language codes:
English: en
Japanese: ja
French: fr
Deutsch: de
Netherlands: nl
Italian: it
Spanish: es
Portugues: pt
Korean: ko
Simplified Chinese: zh-Hans
Traditional Chinese: zh-Hant
The full list can be accessed through the following call:
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
// print each NSString in languages
PostgreSQL: Advanced PostgreSQL
Transactions:
begin work;
// do query
commit work;
begin work;
// do query
rollback work; // undo
begin work;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; // serialize, data doesn't change
// do query
commit work;
begin work;
// do query. End with FOR UPDATE; this serializes & locks this transaction until I update or transaction ends
// do update
commit work;
INDEX: Speeds up searches
create index [indexname] on [tbl] ( [col1], [col2] );
drop index [indexname];
create unique index [indexname] on [tbl] ( [col1], [col2] );
CLUSTER: Speeds up searches by clustering large search results
VACUUM: Speeds up searches by cleaning up expired rows
vacuum [tbl];
vacuum analyze [tbl];
EXPLAIN: Shows speed & statistic on queries
explain select * from [tbl];
LIMIT:
select * from [tbl] limit #;
select * from [tbl] limit # offset #;
CURSOR: must take place inside a transaction
begin work;
declare [cursor name] cursor for select [col] from [tbl];
fetch # from [cursor name];
move #from [cursor name];
close [cursor name];
commit work;
Temporary tables
select * into temporary [tbl] from [tbl2] where [condition];
Alter table content:
alter table [tbl] rename to [tbl'];
alter table [tbl] rename column [col] to [col'];
alter table [tbl] add column [col] [type];
alter table [tbl] alter column [col] [type];
alter table [tbl] alter column [col] set default [value];
alter table [tbl] alter column [col] drop default;
Grant permission:
grant select on [tbl] to [user];
grant all on [tbl] to public;
Inheritance:
create table [tbl] ( ... );
create table [tb2] ( ... ) inherits ( [tbl1] );
select * from [tbl1]*; // access shared columns in tbl1 & tbl2
Views: Views cannot be directly modified, just queried
create view [viewname] as [select ...];
drop view [viewname];
Rules:
create rule [rulename] as on select to [tbl/view] do instead nothing;
create rule [rulename] as on insert to [tbl/view] do instead [what to do];
create rule [rulename] as on update to [tbl/view] do instead [what to do];
create rule [rulename] as on deleete to [tbl/view] do instead [what to do];
Constraints: NOT NULL, UNIQUE, PRIMARY KEY
create table [tbl] ( col1 INTEGER NOT NULL DEFAULT [value] );
create table [tbl] ( col1 INTEGER UNIQUE );
create table [tbl] ( col1 INTEGER PRIMARY KEY ); // UNIQUE+NOT NULL
create table [tbl] (
col1 INTEGER,
col2 INTEGER,
UNIQUE(col1, col2) // must be on its own line
);
create table [tbl] (
col1 INTEGER,
col2 INTEGER,
PRIMARY KEY(col1, col2) // must be on its own line
);
Foreign Key:
create table [tbl1] ( col INTEGER PRIMARY KEY );
create table [tbl2] ( col INTEGER REFERENCES [tbl1] );
Foreign Key Options:
create table [tbl2] ( col INTEGER REFERENCES [tbl1] on update CASCADE on delete SET NULL );
where:
NO ACTION = UPDATEs and DELETEs to the primary key are prohibited if referenced by a foreign key row. (Default)
CASCADE = UPDATEs to the primary key update all foreign key columns that reference it. DELETEs on the primary key cause the deletion of all foreign key rows that reference it.
SET NULL = UPDATEs and DELETEs to the primary key row cause the foreign key to be set to NULL.
CHECK: validity checking during insertion
create table [tbl] ( age INTEGER CHECK (age > 18) );
create table [tbl] ( gender CHAR(1) CHECK (gender IN ('M', 'F') );
create table [tbl] ( age INTEGER, gender CHAR(1), CHECK ( age > 18 and gender in ('M', 'F') ) );
begin work;
// do query
commit work;
begin work;
// do query
rollback work; // undo
begin work;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; // serialize, data doesn't change
// do query
commit work;
begin work;
// do query. End with FOR UPDATE; this serializes & locks this transaction until I update or transaction ends
// do update
commit work;
INDEX: Speeds up searches
create index [indexname] on [tbl] ( [col1], [col2] );
drop index [indexname];
create unique index [indexname] on [tbl] ( [col1], [col2] );
CLUSTER: Speeds up searches by clustering large search results
VACUUM: Speeds up searches by cleaning up expired rows
vacuum [tbl];
vacuum analyze [tbl];
EXPLAIN: Shows speed & statistic on queries
explain select * from [tbl];
LIMIT:
select * from [tbl] limit #;
select * from [tbl] limit # offset #;
CURSOR: must take place inside a transaction
begin work;
declare [cursor name] cursor for select [col] from [tbl];
fetch # from [cursor name];
move #from [cursor name];
close [cursor name];
commit work;
Temporary tables
select * into temporary [tbl] from [tbl2] where [condition];
Alter table content:
alter table [tbl] rename to [tbl'];
alter table [tbl] rename column [col] to [col'];
alter table [tbl] add column [col] [type];
alter table [tbl] alter column [col] [type];
alter table [tbl] alter column [col] set default [value];
alter table [tbl] alter column [col] drop default;
Grant permission:
grant select on [tbl] to [user];
grant all on [tbl] to public;
Inheritance:
create table [tbl] ( ... );
create table [tb2] ( ... ) inherits ( [tbl1] );
select * from [tbl1]*; // access shared columns in tbl1 & tbl2
Views: Views cannot be directly modified, just queried
create view [viewname] as [select ...];
drop view [viewname];
Rules:
create rule [rulename] as on select to [tbl/view] do instead nothing;
create rule [rulename] as on insert to [tbl/view] do instead [what to do];
create rule [rulename] as on update to [tbl/view] do instead [what to do];
create rule [rulename] as on deleete to [tbl/view] do instead [what to do];
Constraints: NOT NULL, UNIQUE, PRIMARY KEY
create table [tbl] ( col1 INTEGER NOT NULL DEFAULT [value] );
create table [tbl] ( col1 INTEGER UNIQUE );
create table [tbl] ( col1 INTEGER PRIMARY KEY ); // UNIQUE+NOT NULL
create table [tbl] (
col1 INTEGER,
col2 INTEGER,
UNIQUE(col1, col2) // must be on its own line
);
create table [tbl] (
col1 INTEGER,
col2 INTEGER,
PRIMARY KEY(col1, col2) // must be on its own line
);
Foreign Key:
create table [tbl1] ( col INTEGER PRIMARY KEY );
create table [tbl2] ( col INTEGER REFERENCES [tbl1] );
Foreign Key Options:
create table [tbl2] ( col INTEGER REFERENCES [tbl1] on update CASCADE on delete SET NULL );
where:
NO ACTION = UPDATEs and DELETEs to the primary key are prohibited if referenced by a foreign key row. (Default)
CASCADE = UPDATEs to the primary key update all foreign key columns that reference it. DELETEs on the primary key cause the deletion of all foreign key rows that reference it.
SET NULL = UPDATEs and DELETEs to the primary key row cause the foreign key to be set to NULL.
CHECK: validity checking during insertion
create table [tbl] ( age INTEGER CHECK (age > 18) );
create table [tbl] ( gender CHAR(1) CHECK (gender IN ('M', 'F') );
create table [tbl] ( age INTEGER, gender CHAR(1), CHECK ( age > 18 and gender in ('M', 'F') ) );
PostgreSQL: Data Types, Functions
display all data types: \dT
Data Types: (Page 108)
TEXT, VARCHAR(length), CHAR(length)
INTEGER, INT2, INT8, OID, NUMERIC(precision, decimal), FLOAT, FLOAT4
DATE, TIME, TIMESTAMP, INTERVAL
BOOLEAN
POINT, LSEG, PATH, BOX, CIRCLE, POLYGON
INET, CIDR, MACADDR
Array Example:
create table [tbl] ( col INTEGER[5] );
insert into [tbl] values ( '{1, 2, 3, 4, 5}' );
Functions: (Page 113)
length(), character_length(), trim(), upper(), lower(), substr(), to_number()
round(), trunc(), abs(), factorial(), sqrt(), cbrt(), exp(), ln(), log(), to_char()
date_part(), now(), timeofday()
Variables:
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
Casts:
CAST('5/8/1982' AS DATE)
CAST('5/8/1982' AS TIMESTAMP)
Data Types: (Page 108)
TEXT, VARCHAR(length), CHAR(length)
INTEGER, INT2, INT8, OID, NUMERIC(precision, decimal), FLOAT, FLOAT4
DATE, TIME, TIMESTAMP, INTERVAL
BOOLEAN
POINT, LSEG, PATH, BOX, CIRCLE, POLYGON
INET, CIDR, MACADDR
Array Example:
create table [tbl] ( col INTEGER[5] );
insert into [tbl] values ( '{1, 2, 3, 4, 5}' );
Functions: (Page 113)
length(), character_length(), trim(), upper(), lower(), substr(), to_number()
round(), trunc(), abs(), factorial(), sqrt(), cbrt(), exp(), ln(), log(), to_char()
date_part(), now(), timeofday()
Variables:
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
Casts:
CAST('5/8/1982' AS DATE)
CAST('5/8/1982' AS TIMESTAMP)
SVN: Troubleshooting
Rule: DO NOT EVER EDIT SVN DB FILES DIRECTLY!
The problem: Wanted to fix the log message for a specific revision.
My (bad) solution: Edit db/revprops/### directly.
This causes the following error:
svn: General svn error from server
To fix this, copy another ### file and overwrite the bad one you altered. After that you should be back in business, just with a bad log.
Now to change the log the PROPER way, go on the server computer and type:
echo "my message goes here" >> msg
svnadmin setlog /Path/to/repo -r #REV# msg
The problem: Wanted to fix the log message for a specific revision.
My (bad) solution: Edit db/revprops/### directly.
This causes the following error:
svn: General svn error from server
To fix this, copy another ### file and overwrite the bad one you altered. After that you should be back in business, just with a bad log.
Now to change the log the PROPER way, go on the server computer and type:
echo "my message goes here" >> msg
svnadmin setlog /Path/to/repo -r #REV# msg
PostgreSQL: Intermediate PostgreSQL
Aggregates:
Return # of rows: COUNT(*)
Return count of NON-NULL values in a column: COUNT(colname)
SUM(colname)
MAX(colname)
MIN(colname)
AVG(colname)
Grouping aggregates: GROUP BY
select [col], aggregate#1, aggregate#2 from [tbl] group by [col], [aggregate#1];
Aggregate conditionals: HAVING
select [col], aggregate#1 from [tbl] group by [col] having [aggregate condition];
Alias:
select [col] from [tbl] [alias] where [alias].[col?] = [condition];
select [col] from [tbl] [alias1], [tbl] [alias2] where [condition];
Joining:
select [tbl].[col] from [tbl1], [tbl2] where [tbl1].[col] = [tb2].[col];
Distinct: Return distinct col1+col2 pairs only
select distinct [col1], [col2], count(*) from [tbl] where [condition];
Unjoined table: Cartesian product
select * from [tbl1], [tb2];
Nonequijoin: (Could be any of <, <>, !=, >)
select [col] from [tbl] [alias1], [tbl] [alias2] where [alias1].[col1] <> [alias2].[col2];
OIDs: Automatically incremented & always distinct
select oid, [col] from [tbl];
create table [tbl] ( customer_oid OID );
AUTO-Numbering / Sequences:
create sequence [sequence name];
create table [tbl] ( customer_id INTEGER DEFAULT nextval('[sequence name]') );
insert into [tbl] values ( nextval('[sequence name]') );
currval('[sequence name]');
setval('[sequence name]', #);
create table [tbl] ( customer_id SERIAL ); // alternative
UNION: Combined results, A and B
select [col1] from [tbl1] union select [col2] from [tbl2];
select [col1] from [tbl1] union all select [col2] from [tbl2]; // with duplicates
EXCEPT: A but not in B
select [col1] from [tbl1] except select [col2] from [tbl2];
INTERSECT: A and in B
select [col1] from [tbl1] intersect select [col2] from [tbl2];
SUBQUERIES: Select within a select, bypass joins
select [col2] from [tbl2] where [col2] <> ( select [col1] from [tbl1] where [condition] );
SUBQUERIES W/ LISTS: Using IN/NOT IN/ANY/ALL/EXISTS/NOT EXISTS
select [col2] from [tbl2] where [col2] in ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] not in ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] any ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] all ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] exists ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] not exists ( select [col1] from [tbl1] where [condition] );
UPDATE + FROM:
update [tbl1] set [col]=[val] from [tbl2] where [condition w/ tbl1 + tbl2];
INSERT USING SELECTS: transfer data from table 1 to 2
insert into [tbl1] (name) select 'danny' from [tbl2];
SELECT INTO: copy table 1 to 2
select [col1], [col2] into [tbl2] from [tbl1];
Text concatenation: ||
'Danny' || 'Cool' = 'DannyCool'
Return # of rows: COUNT(*)
Return count of NON-NULL values in a column: COUNT(colname)
SUM(colname)
MAX(colname)
MIN(colname)
AVG(colname)
Grouping aggregates: GROUP BY
select [col], aggregate#1, aggregate#2 from [tbl] group by [col], [aggregate#1];
Aggregate conditionals: HAVING
select [col], aggregate#1 from [tbl] group by [col] having [aggregate condition];
Alias:
select [col] from [tbl] [alias] where [alias].[col?] = [condition];
select [col] from [tbl] [alias1], [tbl] [alias2] where [condition];
Joining:
select [tbl].[col] from [tbl1], [tbl2] where [tbl1].[col] = [tb2].[col];
Distinct: Return distinct col1+col2 pairs only
select distinct [col1], [col2], count(*) from [tbl] where [condition];
Unjoined table: Cartesian product
select * from [tbl1], [tb2];
Nonequijoin: (Could be any of <, <>, !=, >)
select [col] from [tbl] [alias1], [tbl] [alias2] where [alias1].[col1] <> [alias2].[col2];
OIDs: Automatically incremented & always distinct
select oid, [col] from [tbl];
create table [tbl] ( customer_oid OID );
AUTO-Numbering / Sequences:
create sequence [sequence name];
create table [tbl] ( customer_id INTEGER DEFAULT nextval('[sequence name]') );
insert into [tbl] values ( nextval('[sequence name]') );
currval('[sequence name]');
setval('[sequence name]', #);
create table [tbl] ( customer_id SERIAL ); // alternative
UNION: Combined results, A and B
select [col1] from [tbl1] union select [col2] from [tbl2];
select [col1] from [tbl1] union all select [col2] from [tbl2]; // with duplicates
EXCEPT: A but not in B
select [col1] from [tbl1] except select [col2] from [tbl2];
INTERSECT: A and in B
select [col1] from [tbl1] intersect select [col2] from [tbl2];
SUBQUERIES: Select within a select, bypass joins
select [col2] from [tbl2] where [col2] <> ( select [col1] from [tbl1] where [condition] );
SUBQUERIES W/ LISTS: Using IN/NOT IN/ANY/ALL/EXISTS/NOT EXISTS
select [col2] from [tbl2] where [col2] in ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] not in ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] any ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] all ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] exists ( select [col1] from [tbl1] where [condition] );
select [col2] from [tbl2] where [col2] not exists ( select [col1] from [tbl1] where [condition] );
UPDATE + FROM:
update [tbl1] set [col]=[val] from [tbl2] where [condition w/ tbl1 + tbl2];
INSERT USING SELECTS: transfer data from table 1 to 2
insert into [tbl1] (name) select 'danny' from [tbl2];
SELECT INTO: copy table 1 to 2
select [col1], [col2] into [tbl2] from [tbl1];
Text concatenation: ||
'Danny' || 'Cool' = 'DannyCool'
PostgreSQL: Regular Expression Query
Taken from PostgreSQL Introduction & Concepts
regular expression: ~
regular expression (case-insensitive): ~*
not equal to regular expression: !~
not equal to regular expression (case-insensitive): !~*
Basic Rules:
start: ^
end: $
any single character: .
set of characters: [abc]
set of characters not equal: [^abc]
range of characters: [a-z]
range of characters not equal: [^a-z]
zero or 1: ?
zero or more: *
one or more: +
OR: |
Examples:
begins with D: ~ '^D'
contains D: ~ 'D'
D in second position: ~ '^.D'
begins with D and contains e: ~ 'D.*e'
begins with D, contains e, then f: ~ '^D.*e.*f'
contains A, B, C, or D: ~ '[A-D]' or ~ '[ABCD]'
contains A or a: ~ * 'a' or ~ '[Aa]'
does not contain D: !~ 'D'
does not begin with D: !~ '^D' or ~ '^[^D]'
begin with D, one optional space in front: ~ '^ ?D'
begin with D, with optional leading spaces: ~ '^ *D'
begin with D, with at least 1 space: ~ '^ +D'
end with G, with optional trailing spaces: ~ 'G *$'
regular expression: ~
regular expression (case-insensitive): ~*
not equal to regular expression: !~
not equal to regular expression (case-insensitive): !~*
Basic Rules:
start: ^
end: $
any single character: .
set of characters: [abc]
set of characters not equal: [^abc]
range of characters: [a-z]
range of characters not equal: [^a-z]
zero or 1: ?
zero or more: *
one or more: +
OR: |
Examples:
begins with D: ~ '^D'
contains D: ~ 'D'
D in second position: ~ '^.D'
begins with D and contains e: ~ 'D.*e'
begins with D, contains e, then f: ~ '^D.*e.*f'
contains A, B, C, or D: ~ '[A-D]' or ~ '[ABCD]'
contains A or a: ~ * 'a' or ~ '[Aa]'
does not contain D: !~ 'D'
does not begin with D: !~ '^D' or ~ '^[^D]'
begin with D, one optional space in front: ~ '^ ?D'
begin with D, with optional leading spaces: ~ '^ *D'
begin with D, with at least 1 space: ~ '^ +D'
end with G, with optional trailing spaces: ~ 'G *$'
PostgreSQL: Basic PostgreSQL & SQL
After years of messing with MySQL, I am finally getting into PostgreSQL. The transition was not as easy as I had hoped.
To enter a database:
psql [dbname] -U [username]
Get list of SQL commands: \h
Get help: \?
To exit a database: \q
To clear the buffer: \r
To print the current query: \p
List all tables: \d
Expanded display (instead of columns): \x
List all functions: \df
List all functions named X: \df [function name]
Describe a function: \dd [function name]
Describe an operator: \do [operator ie. ! ^ * + -]
Commentting:
-- a single line comment
/* */ multi-line comment
Create new user:
create user [username] with password '[password]' [createdb/nocreatedb] in group [groupname] valid until 'Jan 1 2005';
Create database:
create database [dbname] with owner [1], [2] encoding = 'UTF8';
Common data types:
CHAR(length), VARCHAR(length)
INTEGER, FLOAT, NUMERIC(precision/decimal)
DATE, TIME, TIMESTAMP
Create table:
create table [tblname] (firstname CHAR(15), lastname CHAR(20), age INTEGER);
create table [tblname] (firstname CHAR(15) default 'no name');
Delete table:
drop table [tblname];
Describe specific table:
\d [tblname];
Insert table content:
insert into [tblname] values ('firstname', 'lastname', 20);
Delete table content:
delete from [tblname]; (deletes all)
delete from [tblname] where [condition];
Update table content:
update [tblname] set [colname]=[new value] where [condition];
Display table content:
select * from [tblname] where age<=20; select * from [tblname] where age>=18 and firstname='danny';
Display table content w/ specified column name:
select [colname] as [tmp-alt colname] from [tblname] order by [tmp-alt colname];
select 1+3 as total;
Display table content w/ specific ordering:
select * from [tblname] where [condition] order by [col1] DESC, [col2], [col3] DESC;
Conditional query:
select [colname] case when [condition w/ colname] then [conditional string value for yes] else [conditional string value for no] end as [casename] from [tblname];
select [colname] case when [condition 1 w/ colname] then [case string value 1 for yes] when [condition 2 w/ colname] then [case string value 2 for yes] else [string value for no] end as [casename] from [tblname];
Grabbing distinct column values from table:
select distinct [colname] from [tblname];
select distinct [col1], [col2] from [tblname];
Example Conditions:
age <> 99
age IS NULL
age != 22 and (firstname='jack' or firstname='bob')
age between 33 and 35
Like Conditions:
like 'D%' (begins with D)
like '%D%' (contains a D)
like '_D%' (has D in second position)
like 'D_nny' (Donny, Danny, Denny)
like 'D%e%' (begins with D contains e)
like 'D%e%f%' (begins with D contains e, then f)
not like 'D%' (begins with non-D)
Common vars:
select current_user;
select current_timestamp;
To enter a database:
psql [dbname] -U [username]
Get list of SQL commands: \h
Get help: \?
To exit a database: \q
To clear the buffer: \r
To print the current query: \p
List all tables: \d
Expanded display (instead of columns): \x
List all functions: \df
List all functions named X: \df [function name]
Describe a function: \dd [function name]
Describe an operator: \do [operator ie. ! ^ * + -]
Commentting:
-- a single line comment
/* */ multi-line comment
Create new user:
create user [username] with password '[password]' [createdb/nocreatedb] in group [groupname] valid until 'Jan 1 2005';
Create database:
create database [dbname] with owner [1], [2] encoding = 'UTF8';
Common data types:
CHAR(length), VARCHAR(length)
INTEGER, FLOAT, NUMERIC(precision/decimal)
DATE, TIME, TIMESTAMP
Create table:
create table [tblname] (firstname CHAR(15), lastname CHAR(20), age INTEGER);
create table [tblname] (firstname CHAR(15) default 'no name');
Delete table:
drop table [tblname];
Describe specific table:
\d [tblname];
Insert table content:
insert into [tblname] values ('firstname', 'lastname', 20);
Delete table content:
delete from [tblname]; (deletes all)
delete from [tblname] where [condition];
Update table content:
update [tblname] set [colname]=[new value] where [condition];
Display table content:
select * from [tblname] where age<=20; select * from [tblname] where age>=18 and firstname='danny';
Display table content w/ specified column name:
select [colname] as [tmp-alt colname] from [tblname] order by [tmp-alt colname];
select 1+3 as total;
Display table content w/ specific ordering:
select * from [tblname] where [condition] order by [col1] DESC, [col2], [col3] DESC;
Conditional query:
select [colname] case when [condition w/ colname] then [conditional string value for yes] else [conditional string value for no] end as [casename] from [tblname];
select [colname] case when [condition 1 w/ colname] then [case string value 1 for yes] when [condition 2 w/ colname] then [case string value 2 for yes] else [string value for no] end as [casename] from [tblname];
Grabbing distinct column values from table:
select distinct [colname] from [tblname];
select distinct [col1], [col2] from [tblname];
Example Conditions:
age <> 99
age IS NULL
age != 22 and (firstname='jack' or firstname='bob')
age between 33 and 35
Like Conditions:
like 'D%' (begins with D)
like '%D%' (contains a D)
like '_D%' (has D in second position)
like 'D_nny' (Donny, Danny, Denny)
like 'D%e%' (begins with D contains e)
like 'D%e%f%' (begins with D contains e, then f)
not like 'D%' (begins with non-D)
Common vars:
select current_user;
select current_timestamp;
PostgreSQL: Setting up PostgreSQL in Mac OSX
NOTE: Do NOT mix the 2 methods. Once you install using the dmg, you will lose access to the server data. However you will gain the use of pgAdmin, which is very similar to SQLServer (from what I remember anyway...).
One method is to download the .dmg from their website, which automatically sets up everything for you, including database URL, port, username & password.
The other method is to do this yourself via command-line:
1. mkdir /DB/data
2. chmod 0700 /DB/data
3. initdb -D /DB/data
4. pg_ctl start -D /DB/data
5. pg_ctl stop -D /DB/data
You can use a simple shell script to start/stop/restart the server for you (taken from Will Green)
#!/bin/bash
export PGDATA=/DB/data
start() {
echo -n "Starting Postgres: "
pg_ctl start -l $PGDATA/postgres.log
return
}
stop() {
echo -n "Shutting down Postgres: "
pg_ctl stop -l $PGDATA/postgres.log
return
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: {start|stop|restart}"
exit 1
;;
esac
exit $?
One method is to download the .dmg from their website, which automatically sets up everything for you, including database URL, port, username & password.
The other method is to do this yourself via command-line:
1. mkdir /DB/data
2. chmod 0700 /DB/data
3. initdb -D /DB/data
4. pg_ctl start -D /DB/data
5. pg_ctl stop -D /DB/data
You can use a simple shell script to start/stop/restart the server for you (taken from Will Green)
#!/bin/bash
export PGDATA=/DB/data
start() {
echo -n "Starting Postgres: "
pg_ctl start -l $PGDATA/postgres.log
return
}
stop() {
echo -n "Shutting down Postgres: "
pg_ctl stop -l $PGDATA/postgres.log
return
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: {start|stop|restart}"
exit 1
;;
esac
exit $?
SVN: Setting up SVN w/ Apache
First of all, I should mention there are typically 2 ways to access SVN:
1. http://url.com
2. svn://url.com
The following steps helps you set up the directory access for method 1. Accessing through http protocol.
Step 1. Install Apache
Step 2. Install Subversion
Step 3. Set environment path=subversion/bin
Step 4. Edit Apache httpd.conf (module section). Add the following lines:
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
Step 5. Copy the modules from Subversion/bin into Apache/modules
Step 6. Add new VirtualHost entry:
< VirtualHost ip:port>
ServerAdmin webmaster@url.com
DocumentRoot c:/wwwroot
ServerName svn.url.com
LogLevel warn
ErrorLog logs/svn.url.com.error.log
CustomLog logs/svn.url.com.access.log common
< Location>
DAV svn
SVNParentPath c:/svnroot
SVNListParentPath on
AuthzSVNAccessFile c:/svnrepo/conf/authz
AuthType Basic
AuthName "Kronos SVN"
AuthUserFile c:/svnrepo/conf/htpasswd
Require valid-user
< /Location>
< /VirtualHost>
Step 7. Customize authz file
[groups]
admin = bob, joe, mike
visitor = dan, steve, matt
[reponame:/]
* =
@admin = rw
@visitor = r
[reponame:/subdir/]
* =
@admin = rw
@visitor =
Step 8. Customize htpasswd file
use apache/bin/htpasswd.exe to create htpasswd file: htpasswd.exe -c /path/htpasswd user1
add aditional users to htpasswd file: htpasswd.exe /path/htpasswd user2
Step 9. Restart your apache server
To set up directory access for method 2, accessing through svn port directly is much simpler, but does not offer the encrypted password protection offered in method 1. The trick is, you can actually have BOTH.
For the admin account I like to use the http access w/ encrypted protection. For additional accounts, just to make things simpler, I use the svn passwd file which typically just looks like this:
[users]
user1=password1
user2=password2
Just make sure you adjust the svn configuration file accordingly & you should be all set. Restart your svn server after changing the configuration file.
1. http://url.com
2. svn://url.com
The following steps helps you set up the directory access for method 1. Accessing through http protocol.
Step 1. Install Apache
Step 2. Install Subversion
Step 3. Set environment path=subversion/bin
Step 4. Edit Apache httpd.conf (module section). Add the following lines:
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
Step 5. Copy the modules from Subversion/bin into Apache/modules
Step 6. Add new VirtualHost entry:
< VirtualHost ip:port>
ServerAdmin webmaster@url.com
DocumentRoot c:/wwwroot
ServerName svn.url.com
LogLevel warn
ErrorLog logs/svn.url.com.error.log
CustomLog logs/svn.url.com.access.log common
< Location>
DAV svn
SVNParentPath c:/svnroot
SVNListParentPath on
AuthzSVNAccessFile c:/svnrepo/conf/authz
AuthType Basic
AuthName "Kronos SVN"
AuthUserFile c:/svnrepo/conf/htpasswd
Require valid-user
< /Location>
< /VirtualHost>
Step 7. Customize authz file
[groups]
admin = bob, joe, mike
visitor = dan, steve, matt
[reponame:/]
* =
@admin = rw
@visitor = r
[reponame:/subdir/]
* =
@admin = rw
@visitor =
Step 8. Customize htpasswd file
use apache/bin/htpasswd.exe to create htpasswd file: htpasswd.exe -c /path/htpasswd user1
add aditional users to htpasswd file: htpasswd.exe /path/htpasswd user2
Step 9. Restart your apache server
To set up directory access for method 2, accessing through svn port directly is much simpler, but does not offer the encrypted password protection offered in method 1. The trick is, you can actually have BOTH.
For the admin account I like to use the http access w/ encrypted protection. For additional accounts, just to make things simpler, I use the svn passwd file which typically just looks like this:
[users]
user1=password1
user2=password2
Just make sure you adjust the svn configuration file accordingly & you should be all set. Restart your svn server after changing the configuration file.
SVN: Configure Authorizations
Disallow anonymous access:
anon-access=none
auth-access=write
Allow anonymouse access:
anon-access=read
auth-access=write
anon-access=none
auth-access=write
Allow anonymouse access:
anon-access=read
auth-access=write
Subscribe to:
Posts (Atom)