Home Page
Home
Home

Site BEST viewed with:
FireFox & JavaScript
Compatible with: IE6+
Further info here.
RSS
Search:
RABiD BUNNY FEVER
K.T.K

Warning: you do not have javascript enabled. This WILL cause layout glitches.

Welcome to my domain. This is an open space where I, Jeffrey Riaboy, am keeping a compendium of my projects, thoughts, news, and miscellaneous ideas. I am a self taught programmer/computer nerd that works in C++ by choice, and too many other languages due to the facts of life. I have been programming virtually my whole life and working with computers since before I can remember. They are my passion, hobby, job, first love, and have served me well, though, been a constant pain in the anatomy. I hope you can find something of interest or use here, as that is the reason I spend my time creating and organizing this content. Enjoy. ^_^
Dakusan~
The original (well... last) intro page to my website before this became the home. It is a flash portal to my personal sites of the past.
Intro
[1999-2001?] My ancient NES emulator made in Visual Basic (which was made to prove the power and flexibility [not speed] of the language). But alas, one of my friends, David Finch beat me to it by optimizing BasicNes [Don Jarrett].
HyNes
[2002] A chronicle of my experiences and tinkering from early ’02 to early ’04 on an addictive yet horribly crappy MMORPG. Site also has some nice “hacking”/reverse engineering tutorials.
Ragnarok Hacking
I’ve temporarily set this to link to the Projects section of this website until I’m ready to announce the new website this will link to.
Projects
Updates Archive
Updated:07/15/16
Plex Playlist Importer v1.1 (source). Current updates spanning 2017:
  • Fixed absolute path logic for Linux (partial credit to Matt Spitz)
  • Bypasses UTF8 BOM
  • Program now works off of argument flags.
    • Added parameters: Playlist encoding, override type, force list
    • Created special BulletHelpFormatter class for parameters
  • Playlist names can now conflict with other item/list names in Plex
  • Console column width passthrough in the .sh file
  • Updated READMEs regarding:
    • Unicode compliance
    • The “no such module : FTS4” error
    • Running the script from a computer external to the server running Plex
    • The “The program can’t start because MSVCR100.dll is missing” error
    • All updates
  • Added the ability to compile to a windows executable (via setup.py py2exe)
  • The Playlist Name is now an optional argument which can be entered after the program is ran. This allows directly dragging playlists onto the executable
  • Added shebang to main script
  • M3U files now ignore lines that are empty or have only whitespace
Download Content
Section: Projects > Websites
Updated:02/08/16
Section: Misc > Resume
Updated:02/07/16
  • Rewrote the background section, which was badly needed.
  • Under Notable Projects, made Intellitix past tense (as of 2012)
  • Added Notable Project C2MTL
  • Removed Obsolete Skills: VBScript
  • Added Skills: AngularJS, Django, jQuery, Amazon Web Services
  • Work Experience/Deltaarc: Specified IT Admin for Linux servers
  • Removed Obsolete Jobs and Skills:
    • Tutor at Open Doors Learning Center [1999-2001]
    • Microsoft Certified Professional [2004]
    • Place in Winston Science Programming Competition [1999, 2000, 2002]
    • Black Belt in Taekwondo [1996]
Download Content
Post Archive
RSS Feed
Painless migration from PHP MySQL to MySQLi

The PHP MySQL extension is being deprecated in favor of the MySQLi extension in PHP 5.5, and removed as of PHP 7.0. MySQLi was first referenced in PHP v5.0.0 beta 4 on 2004-02-12, with the first stable release in PHP 5.0.0 on 2004-07-13[1]. Before that, the PHP MySQL extension was by far the most popular way of interacting with MySQL on PHP, and still was for a very long time after. This website was opened only 2 years after the first stable release!


With the deprecation, problems from some websites I help host have popped up, many of these sites being very, very old. I needed a quick and dirty solution to monkey-patch these websites to use MySQLi without rewriting all their code. The obvious answer is to overwrite the functions with wrappers for MySQLi. The generally known way of doing this is with the Advanced PHP Debugger (APD). However, using this extension has a lot of requirements that are not appropriate for a production web server. Fortunately, another extension I recently learned of offers the renaming functionality; runkit. It was a super simple install for me.

  1. From the command line, run “pecl install runkit”
  2. Add “extension=runkit.so” and “runkit.internal_override=On” to the php.ini

Besides the ability to override these functions with wrappers, I also needed a way to make sure this file was always loaded before all other PHP files. The simple solution for that is adding “auto_prepend_file=/PATH/TO/FILE” to the “.user.ini” in the user’s root web directory.

The code for this script is as follows. It only contains a limited set of the MySQL functions, including some very esoteric ones that the web site used. This is not a foolproof script, but it gets the job done.


//Override the MySQL functions
foreach(Array(
    'connect', 'error', 'fetch_array', 'fetch_row', 'insert_id', 'num_fields', 'num_rows',
    'query', 'select_db', 'field_len', 'field_name', 'field_type', 'list_dbs', 'list_fields',
    'list_tables', 'tablename'
) as $FuncName)
    runkit_function_redefine("mysql_$FuncName", '',
        'return call_user_func_array("mysql_'.$FuncName.'_OVERRIDE", func_get_args());');

//If a connection is not explicitely passed to a mysql_ function, use the last created connection
global $SQLLink; //The remembered SQL Link
function GetConn($PassedConn)
{
    if(isset($PassedConn))
        return $PassedConn;
    global $SQLLink;
    return $SQLLink;
}

//Override functions
function mysql_connect_OVERRIDE($Host, $Username, $Password) {
    global $SQLLink;
    return $SQLLink=mysqli_connect($Host, $Username, $Password);
}
function mysql_error_OVERRIDE($SQLConn=NULL) {
    return mysqli_error(GetConn($SQLConn));
}
function mysql_fetch_array_OVERRIDE($Result, $ResultType=MYSQL_BOTH) {
    return mysqli_fetch_array($Result, $ResultType);
}
function mysql_fetch_row_OVERRIDE($Result) {
    return mysqli_fetch_row($Result);
}
function mysql_insert_id_OVERRIDE($SQLConn=NULL) {
    return mysqli_insert_id(GetConn($SQLConn));
}
function mysql_num_fields_OVERRIDE($Result) {
    return mysqli_num_fields($Result);
}
function mysql_num_rows_OVERRIDE($Result) {
    return mysqli_num_rows($Result);
}
function mysql_query_OVERRIDE($Query, $SQLConn=NULL) {
    return mysqli_query(GetConn($SQLConn), $Query);
}
function mysql_select_db_OVERRIDE($DBName, $SQLConn=NULL) {
    return mysqli_select_db(GetConn($SQLConn), $DBName);
}
function mysql_field_len_OVERRIDE($Result, $Offset) {
    $Fields=$Result->fetch_fields();
    return $Fields[$Offset]->length;
}
function mysql_field_name_OVERRIDE($Result, $Offset) {
    $Fields=$Result->fetch_fields();
    return $Fields[$Offset]->name;
}
function mysql_field_type_OVERRIDE($Result, $Offset) {
    $Fields=$Result->fetch_fields();
    return $Fields[$Offset]->type;
}
function mysql_list_dbs_OVERRIDE($SQLConn=NULL) {
    $Result=mysql_query('SHOW DATABASES', GetConn($SQLConn));
    $Tables=Array();
    while($Row=mysqli_fetch_assoc($Result))
        $Tables[]=$Row['Database'];
    return $Tables;
}
function mysql_list_fields_OVERRIDE($DBName, $TableName, $SQLConn=NULL) {
    $SQLConn=GetConn($SQLConn);
    $CurDB=mysql_fetch_array(mysql_query('SELECT Database()', $SQLConn));
    $CurDB=$CurDB[0];
    mysql_select_db($DBName, $SQLConn);
    $Result=mysql_query("SHOW COLUMNS FROM $TableName", $SQLConn);
    mysql_select_db($CurDB, $SQLConn);
    if(!$Result) {
        print 'Could not run query: '.mysql_error($SQLConn);
        return Array();
    }
    $Fields=Array();
    while($Row=mysqli_fetch_assoc($Result))
        $Fields[]=$Row['Field'];
    return $Fields;
}
function mysql_list_tables_OVERRIDE($DBName, $SQLConn=NULL) {
    $SQLConn=GetConn($SQLConn);
    $CurDB=mysql_fetch_array(mysql_query('SELECT Database()', $SQLConn));
    $CurDB=$CurDB[0];
    mysql_select_db($DBName, $SQLConn);
    $Result=mysql_query("SHOW TABLES", $SQLConn);
    mysql_select_db($CurDB, $SQLConn);
    if(!$Result) {
        print 'Could not run query: '.mysql_error($SQLConn);
        return Array();
    }
    $Tables=Array();
    while($Row=mysql_fetch_row($Result))
        $Tables[]=$Row[0];
    return $Tables;
}
function mysql_tablename_OVERRIDE($Result) {
    $Fields=$Result->fetch_fields();
    return $Fields[0]->table;
}

And here is some test code to confirm functionality:
global $MyConn, $TEST_Table;
$TEST_Server='localhost';
$TEST_UserName='...';
$TEST_Password='...';
$TEST_DB='...';
$TEST_Table='...';
function GetResult() {
    global $MyConn, $TEST_Table;
    return mysql_query('SELECT * FROM '.$TEST_Table.' LIMIT 1', $MyConn);
}
var_dump($MyConn=mysql_connect($TEST_Server, $TEST_UserName, $TEST_Password));
//Set $MyConn to NULL here if you want to test global $SQLLink functionality
var_dump(mysql_select_db($TEST_DB, $MyConn));
var_dump(mysql_query('SELECT * FROM INVALIDTABLE LIMIT 1', $MyConn));
var_dump(mysql_error($MyConn));
var_dump($Result=GetResult());
var_dump(mysql_fetch_array($Result));
$Result=GetResult(); var_dump(mysql_fetch_row($Result));
$Result=GetResult(); var_dump(mysql_num_fields($Result));
var_dump(mysql_num_rows($Result));
var_dump(mysql_field_len($Result, 0));
var_dump(mysql_field_name($Result, 0));
var_dump(mysql_field_type($Result, 0));
var_dump(mysql_tablename($Result));
var_dump(mysql_list_dbs($MyConn));
var_dump(mysql_list_fields($TEST_DB, $TEST_Table, $MyConn));
var_dump(mysql_list_tables($TEST_DB, $MyConn));
mysql_query('CREATE TEMPORARY TABLE mysqltest (i int auto_increment, primary key (i))', $MyConn);
mysql_query('INSERT INTO mysqltest VALUES ()', $MyConn);
mysql_query('INSERT INTO mysqltest VALUES ()', $MyConn);
var_dump(mysql_insert_id($MyConn));
mysql_query('DROP TEMPORARY TABLE mysqltest', $MyConn);
Bullet Help Formatter for Python’s argparse
This is a HelpFormatter for Python’s argparse class which:
  • Takes raw input and wraps long lines to indent against the current line start.
  • When an indented/list line is encountered, which starts with spaces followed by a star "*", wrapped line’s indents will start 2 spaces after the star.
  • Lines attempt to split at words of 10 characters or less (see .MinCharsInSplitWord).
  • If a line needs to split along a word longer than this, a hyphen is inserted at the end of the line.

import argparse
import re
class BulletHelpFormatter(argparse.HelpFormatter):
    def __init__(self, *args, **kwargs):
        super(BulletHelpFormatter, self).__init__(*args, **kwargs)
        self.MinCharsInSplitWord=10

    def _split_lines(self, text, width):
        #Split lines around line breaks and then modify each line
        Lines=[]
        for Line in text.splitlines():
            #Get the number of spaces to put at subsequent lines
            #0 if not a list item, oherwise, 2+list item start
            ListEl=re.match(r'^ *\*', Line)
            NumBeginningSpace=(0 if ListEl==None else ListEl.end()+1)

            #Add extra spaces at the beginning of each line to match the start of the current line, and go to a maxium of $width
            IsFirstPass=True
            SpacesToAdd=''
            NumSpacesToAdd=0
            while(True):
                #Get the word break points before and after where the line would end
                MaxLineLen=max(min(width-NumSpacesToAdd, len(Line)), 1)
                PrevWordBreak=CurWordBreak=0
                for WordBreak in re.finditer(r'(?<=\W).|\W|$', Line):
                    PrevWordBreak=CurWordBreak
                    CurWordBreak=WordBreak.start()
                    if CurWordBreak>=MaxLineLen:
                        if CurWordBreak==MaxLineLen:
                            PrevWordBreak=CurWordBreak
                        break

                #If previous wordbreak is more than MinCharsInSplitWord away from MaxLineLen, then split at the end of the line
                IsSplit=(PrevWordBreak<1 or CurWordBreak-PrevWordBreak>self.MinCharsInSplitWord)
                SplitPos=(MaxLineLen if IsSplit else PrevWordBreak)

                #Append the new line to the list of lines
                Lines.append(SpacesToAdd+Line[0:SplitPos]+('-' if IsSplit else ''))
                Line=Line[SplitPos:]

                #If this is the end, nothing left to do
                if len(Line)==0:
                    break

                #If this is the first pass, update line creation variables
                if IsFirstPass:
                    IsFirstPass=False
                    NumSpacesToAdd=NumBeginningSpace
                    SpacesToAdd=(' ' * NumSpacesToAdd)

        return Lines
Database list of countries and currencies

I had the need for a project recently to have a database list of countries and currencies. I ended up pulling the currency list from wikipedia and the country list from the stage.gov website. You can download the SQL here, or copy from below. Do note there are NULLs in some of the places where data was unavailable.


DROP TABLE IF EXISTS Countries;
CREATE TABLE Countries (
  ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
  FIPS char(2) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
  Name varchar(35) NOT NULL,
  LongName varchar(55) NOT NULL,
  PRIMARY KEY (ID),
  UNIQUE KEY FIPS (FIPS),
  UNIQUE KEY Name (Name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO Countries (FIPS, Name, LongName) VALUES
  ('AF','Afghanistan','Islamic Republic of Afghanistan'),
  ('AL','Albania','Republic of Albania'),
  ('AG','Algeria','People’s Democratic Republic of Algeria'),
  ('AN','Andorra','Principality of Andorra'),
  ('AO','Angola','Republic of Angola'),
  ('AC','Antigua and Barbuda','Antiqua and Barbuda'),
  ('AR','Argentina','Argentine Republic'),
  ('AM','Armenia','Republic of Armenia'),
  ('AS','Australia','Commonwealth of Australia'),
  ('AU','Austria','Republic of Austria'),
  ('AJ','Azerbaijan','Republic of Azerbaijan'),
  ('BF','Bahamas, The','Commonwealth of The Bahamas'),
  ('BA','Bahrain','Kingdom of Bahrain'),
  ('BG','Bangladesh','People’s Republic of Bangladesh'),
  ('BB','Barbados','Barbados'),
  ('BO','Belarus','Republic of Belarus'),
  ('BE','Belgium','Kingdom of Belgium'),
  ('BH','Belize','Belize'),
  ('BN','Benin','Republic of Benin'),
  ('BT','Bhutan','Kingdom of Bhutan'),
  ('BL','Bolivia','Plurinational State of Bolivia'),
  ('BK','Bosnia and Herzegovina','Bosnia and Herzegovina'),
  ('BC','Botswana','Republic of Botswana'),
  ('BR','Brazil','Federative Republic of Brazil'),
  ('BX','Brunei','Brunei Darussalam'),
  ('BU','Bulgaria','Republic of Bulgaria'),
  ('UV','Burkina Faso','Burkina Faso'),
  ('BM','Burma','Union of Burma'),
  ('BY','Burundi','Republic of Burundi'),
  ('CV','Cabo Verde','Republic of Cabo Verde'),
  ('CB','Cambodia','Kingdom of Cambodia'),
  ('CM','Cameroon','Republic of Cameroon'),
  ('CA','Canada','Canada'),
  ('CT','Central African Republic','Central African Republic'),
  ('CD','Chad','Republic of Chad'),
  ('CI','Chile','Republic of Chile'),
  ('CH','China','People’s Republic of China'),
  ('CO','Colombia','Republic of Colombia'),
  ('CN','Comoros','Union of the Comoros'),
  ('CF','Congo (Brazzaville)','Republic of the Congo'),
  ('CG','Congo (Kinshasa)','Democratic Republic of the Congo'),
  ('CS','Costa Rica','Republic of Costa Rica'),
  ('IV','Côte d’Ivoire','Republic of Côte d’Ivoire'),
  ('HR','Croatia','Republic of Croatia'),
  ('CU','Cuba','Republic of Cuba'),
  ('CY','Cyprus','Republic of Cyprus'),
  ('EZ','Czech Republic','Czech Republic'),
  ('DA','Denmark','Kingdom of Denmark'),
  ('DJ','Djibouti','Republic of Djibouti'),
  ('DO','Dominica','Commonwealth of Dominica'),
  ('DR','Dominican Republic','Dominican Republic'),
  ('EC','Ecuador','Republic of Ecuador'),
  ('EG','Egypt','Arab Republic of Egypt'),
  ('ES','El Salvador','Republic of El Salvador'),
  ('EK','Equatorial Guinea','Republic of Equatorial Guinea'),
  ('ER','Eritrea','State of Eritrea'),
  ('EN','Estonia','Republic of Estonia'),
  ('ET','Ethiopia','Federal Democratic Republic of Ethiopia'),
  ('FJ','Fiji','Republic of Fiji'),
  ('FI','Finland','Republic of Finland'),
  ('FR','France','French Republic'),
  ('GB','Gabon','Gabonese Republic'),
  ('GA','Gambia, The','Republic of The Gambia'),
  ('GG','Georgia','Georgia'),
  ('GM','Germany','Federal Republic of Germany'),
  ('GH','Ghana','Republic of Ghana'),
  ('GR','Greece','Hellenic Republic'),
  ('GJ','Grenada','Grenada'),
  ('GT','Guatemala','Republic of Guatemala'),
  ('GV','Guinea','Republic of Guinea'),
  ('PU','Guinea-Bissau','Republic of Guinea-Bissau'),
  ('GY','Guyana','Co-operative Republic of Guyana'),
  ('HA','Haiti','Republic of Haiti'),
  ('VT','Holy See','Holy See'),
  ('HO','Honduras','Republic of Honduras'),
  ('HU','Hungary','Hungary'),
  ('IC','Iceland','Republic of Iceland'),
  ('IN','India','Republic of India'),
  ('ID','Indonesia','Republic of Indonesia'),
  ('IR','Iran','Islamic Republic of Iran'),
  ('IZ','Iraq','Republic of Iraq'),
  ('EI','Ireland','Ireland'),
  ('IS','Israel','State of Israel'),
  ('IT','Italy','Italian Republic'),
  ('JM','Jamaica','Jamaica'),
  ('JA','Japan','Japan'),
  ('JO','Jordan','Hashemite Kingdom of Jordan'),
  ('KZ','Kazakhstan','Republic of Kazakhstan'),
  ('KE','Kenya','Republic of Kenya'),
  ('KR','Kiribati','Republic of Kiribati'),
  ('KN','Korea, North','Democratic People’s Republic of Korea'),
  ('KS','Korea, South','Republic of Korea'),
  ('KV','Kosovo','Republic of Kosovo'),
  ('KU','Kuwait','State of Kuwait'),
  ('KG','Kyrgyzstan','Kyrgyz Republic'),
  ('LA','Laos','Lao People’s Democratic Republic'),
  ('LG','Latvia','Republic of Latvia'),
  ('LE','Lebanon','Lebanese Republic'),
  ('LT','Lesotho','Kingdom of Lesotho'),
  ('LI','Liberia','Republic of Liberia'),
  ('LY','Libya','Libya'),
  ('LS','Liechtenstein','Principality of Liechtenstein'),
  ('LH','Lithuania','Republic of Lithuania'),
  ('LU','Luxembourg','Grand Duchy of Luxembourg'),
  ('MK','Macedonia','Republic of Macedonia'),
  ('MA','Madagascar','Republic of Madagascar'),
  ('MI','Malawi','Republic of Malawi'),
  ('MY','Malaysia','Malaysia'),
  ('MV','Maldives','Republic of Maldives'),
  ('ML','Mali','Republic of Mali'),
  ('MT','Malta','Republic of Malta'),
  ('RM','Marshall Islands','Republic of the Marshall Islands'),
  ('MR','Mauritania','Islamic Republic of Mauritania'),
  ('MP','Mauritius','Republic of Mauritius'),
  ('MX','Mexico','United Mexican States'),
  ('FM','Micronesia, Federated States of','Federated States of Micronesia'),
  ('MD','Moldova','Republic of Moldova'),
  ('MN','Monaco','Principality of Monaco'),
  ('MG','Mongolia','Mongolia'),
  ('MJ','Montenegro','Montenegro'),
  ('MO','Morocco','Kingdom of Morocco'),
  ('MZ','Mozambique','Republic of Mozambique'),
  ('WA','Namibia','Republic of Namibia'),
  ('NR','Nauru','Republic of Nauru'),
  ('NP','Nepal','Federal Democratic Republic of Nepal'),
  ('NL','Netherlands','Kingdom of the Netherlands'),
  ('NZ','New Zealand','New Zealand'),
  ('NU','Nicaragua','Republic of Nicaragua'),
  ('NG','Niger','Republic of Niger'),
  ('NI','Nigeria','Federal Republic of Nigeria'),
  ('NO','Norway','Kingdom of Norway'),
  ('MU','Oman','Sultanate of Oman'),
  ('PK','Pakistan','Islamic Republic of Pakistan'),
  ('PS','Palau','Republic of Palau'),
  ('PM','Panama','Republic of Panama'),
  ('PP','Papua New Guinea','Independent State of Papua New Guinea'),
  ('PA','Paraguay','Republic of Paraguay'),
  ('PE','Peru','Republic of Peru'),
  ('RP','Philippines','Republic of the Philippines'),
  ('PL','Poland','Republic of Poland'),
  ('PO','Portugal','Portuguese Republic'),
  ('QA','Qatar','State of Qatar'),
  ('RO','Romania','Romania'),
  ('RS','Russia','Russian Federation'),
  ('RW','Rwanda','Republic of Rwanda'),
  ('SC','Saint Kitts and Nevis','Federation of Saint Kitts and Nevis'),
  ('ST','Saint Lucia','Saint Lucia'),
  ('VC','Saint Vincent and the Grenadines','Saint Vincent and the Grenadines'),
  ('WS','Samoa','Independent State of Samoa'),
  ('SM','San Marino','Republic of San Marino'),
  ('TP','Sao Tome and Principe','Democratic Republic of Sao Tome and Principe'),
  ('SA','Saudi Arabia','Kingdom of Saudi Arabia'),
  ('SG','Senegal','Republic of Senegal'),
  ('RI','Serbia','Republic of Serbia'),
  ('SE','Seychelles','Republic of Seychelles'),
  ('SL','Sierra Leone','Republic of Sierra Leone'),
  ('SN','Singapore','Republic of Singapore'),
  ('LO','Slovakia','Slovak Republic'),
  ('SI','Slovenia','Republic of Slovenia'),
  ('BP','Solomon Islands','Solomon Islands'),
  ('SO','Somalia','Federal Republic of Somalia'),
  ('SF','South Africa','Republic of South Africa'),
  ('OD','South Sudan','Republic of South Sudan'),
  ('SP','Spain','Kingdom of Spain'),
  ('CE','Sri Lanka','Democratic Socialist Republic of Sri Lanka'),
  ('SU','Sudan','Republic of the Sudan'),
  ('NS','Suriname','Republic of Suriname'),
  ('WZ','Swaziland','Kingdom of Swaziland'),
  ('SW','Sweden','Kingdom of Sweden'),
  ('SZ','Switzerland','Swiss Confederation'),
  ('SY','Syria','Syrian Arab Republic'),
  ('TI','Tajikistan','Republic of Tajikistan'),
  ('TZ','Tanzania','United Republic of Tanzania'),
  ('TH','Thailand','Kingdom of Thailand'),
  ('TT','Timor-Leste','Democratic Republic of Timor-Leste'),
  ('TO','Togo','Togolese Republic'),
  ('TN','Tonga','Kingdom of Tonga'),
  ('TD','Trinidad and Tobago','Republic of Trinidad and Tobago'),
  ('TS','Tunisia','Republic of Tunisia'),
  ('TU','Turkey','Republic of Turkey'),
  ('TX','Turkmenistan','Turkmenistan'),
  ('TV','Tuvalu','Tuvalu'),
  ('UG','Uganda','Republic of Uganda'),
  ('UP','Ukraine','Ukraine'),
  ('AE','United Arab Emirates','United Arab Emirates'),
  ('UK','United Kingdom','United Kingdom of Great Britain and Northern Ireland'),
  ('US','United States','United States of America'),
  ('UY','Uruguay','Oriental Republic of Uruguay'),
  ('UZ','Uzbekistan','Republic of Uzbekistan'),
  ('NH','Vanuatu','Republic of Vanuatu'),
  ('VE','Venezuela','Bolivarian Republic of Venezuela'),
  ('VM','Vietnam','Socialist Republic of Vietnam'),
  ('YM','Yemen','Republic of Yemen'),
  ('ZA','Zambia','Republic of Zambia'),
  ('ZI','Zimbabwe','Republic of Zimbabwe');

DROP TABLE IF EXISTS Currencies;
CREATE TABLE Currencies (
  ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
  ISOCode char(3) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL,
  NumberToBasic smallint(5) unsigned DEFAULT NULL,
  Symbol varchar(6) DEFAULT NULL,
  Name varchar(55) DEFAULT NULL,
  PRIMARY KEY (ID),
  UNIQUE KEY ISOCode (ISOCode),
  UNIQUE KEY Name (Name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO Currencies (ISOCode, NumberToBasic, Symbol, Name) VALUES
  ('AFN',100,'؋','Afghan afghani'),
  ('ALL',100,'L','Albanian lek'),
  (NULL,100,'£','Alderney pound'),
  ('DZD',100,'د.ج','Algerian dinar'),
  ('AOA',100,'Kz','Angolan kwanza'),
  ('ARS',100,'$','Argentine peso'),
  ('AMD',100,'֏','Armenian dram'),
  ('AWG',100,'ƒ','Aruban florin'),
  (NULL,100,'£','Ascension pound'),
  ('AUD',100,'$','Australian dollar'),
  ('AZN',100,'₼','Azerbaijani manat'),
  ('BSD',100,'$','Bahamian dollar'),
  ('BHD',1000,'.د.ب','Bahraini dinar'),
  ('BDT',100,'৳','Bangladeshi taka'),
  ('BBD',100,'$','Barbadian dollar'),
  ('BYR',100,'Br','Belarusian ruble'),
  ('BZD',100,'$','Belize dollar'),
  ('BMD',100,'$','Bermudian dollar'),
  ('BTN',100,'Nu.','Bhutanese ngultrum'),
  ('BOB',100,'Bs.','Bolivian boliviano'),
  ('BAM',100,'KM','Bosnia and Herzegovina convertible mark'),
  ('BWP',100,'P','Botswana pula'),
  ('BRL',100,'R$','Brazilian real'),
  ('GBP',100,'£','British pound'),
  (NULL,100,'$','British Virgin Islands dollar'),
  ('BND',100,'$','Brunei dollar'),
  ('BGN',100,'лв','Bulgarian lev'),
  ('MMK',100,'Ks','Burmese kyat'),
  ('BIF',100,'Fr','Burundian franc'),
  ('KHR',100,'៛','Cambodian riel'),
  ('CAD',100,'$','Canadian dollar'),
  ('CVE',100,'$','Cape Verdean escudo'),
  ('KYD',100,'$','Cayman Islands dollar'),
  ('XAF',100,'Fr','Central African CFA franc'),
  ('XPF',100,'Fr','CFP franc'),
  ('CLP',100,'$','Chilean peso'),
  ('CNY',100,'¥','Chinese yuan'),
  ('COP',100,'$','Colombian peso'),
  ('KMF',100,'Fr','Comorian franc'),
  ('CDF',100,'Fr','Congolese franc'),
  (NULL,100,'$','Cook Islands dollar'),
  ('CRC',100,'₡','Costa Rican colón'),
  ('HRK',100,'kn','Croatian kuna'),
  ('CUC',100,'$','Cuban convertible peso'),
  ('CUP',100,'$','Cuban peso'),
  ('CZK',100,'Kč','Czech koruna'),
  ('DKK',100,'kr','Danish krone'),
  ('DJF',100,'Fr','Djiboutian franc'),
  ('DOP',100,'$','Dominican peso'),
  ('XCD',100,'$','East Caribbean dollar'),
  ('EGP',100,'£','Egyptian pound'),
  ('ERN',100,'Nfk','Eritrean nakfa'),
  ('ETB',100,'Br','Ethiopian birr'),
  ('EUR',100,'€','Euro'),
  ('FKP',100,'£','Falkland Islands pound'),
  (NULL,100,'kr','Faroese króna'),
  ('FJD',100,'$','Fijian dollar'),
  ('GMD',100,'D','Gambian dalasi'),
  ('GEL',100,'ლ','Georgian lari'),
  ('GHS',100,'₵','Ghana cedi'),
  ('GIP',100,'£','Gibraltar pound'),
  ('GTQ',100,'Q','Guatemalan quetzal'),
  ('GGP',100,'£','Guernsey pound'),
  ('GNF',100,'Fr','Guinean franc'),
  ('GYD',100,'$','Guyanese dollar'),
  ('HTG',100,'G','Haitian gourde'),
  ('HNL',100,'L','Honduran lempira'),
  ('HKD',100,'$','Hong Kong dollar'),
  ('HUF',100,'Ft','Hungarian forint'),
  ('ISK',100,'kr','Icelandic króna'),
  ('INR',100,'₹','Indian rupee'),
  ('IDR',100,'Rp','Indonesian rupiah'),
  ('IRR',100,'﷼','Iranian rial'),
  ('IQD',1000,'ع.د','Iraqi dinar'),
  ('ILS',100,'₪','Israeli new shekel'),
  ('JMD',100,'$','Jamaican dollar'),
  ('JPY',100,'¥','Japanese yen'),
  ('JEP',100,'£','Jersey pound'),
  ('JOD',100,'د.ا','Jordanian dinar'),
  ('KZT',100,'₸','Kazakhstani tenge'),
  ('KES',100,'Sh','Kenyan shilling'),
  (NULL,100,'$','Kiribati dollar'),
  ('KWD',1000,'د.ك','Kuwaiti dinar'),
  ('KGS',100,'лв','Kyrgyzstani som'),
  ('LAK',100,'₭','Lao kip'),
  ('LBP',100,'ل.ل','Lebanese pound'),
  ('LSL',100,'L','Lesotho loti'),
  ('LRD',100,'$','Liberian dollar'),
  ('LYD',1000,'ل.د','Libyan dinar'),
  ('MOP',100,'P','Macanese pataca'),
  ('MKD',100,'ден','Macedonian denar'),
  ('MGA',5,'Ar','Malagasy ariary'),
  ('MWK',100,'MK','Malawian kwacha'),
  ('MYR',100,'RM','Malaysian ringgit'),
  ('MVR',100,'.ރ','Maldivian rufiyaa'),
  ('IMP',100,'£','Manx pound'),
  ('MRO',5,'UM','Mauritanian ouguiya'),
  ('MUR',100,'₨','Mauritian rupee'),
  ('MXN',100,'$','Mexican peso'),
  (NULL,100,'$','Micronesian dollar'),
  ('MDL',100,'L','Moldovan leu'),
  ('MNT',100,'₮','Mongolian tögrög'),
  ('MAD',100,'د. م.','Moroccan dirham'),
  ('MZN',100,'MT','Mozambican metical'),
  (NULL,100,'դր.','Nagorno-Karabakh dram'),
  ('NAD',100,'$','Namibian dollar'),
  (NULL,100,'$','Nauruan dollar'),
  ('NPR',100,'₨','Nepalese rupee'),
  ('ANG',100,'ƒ','Netherlands Antillean guilder'),
  ('TWD',100,'$','New Taiwan dollar'),
  ('NZD',100,'$','New Zealand dollar'),
  ('NIO',100,'C$','Nicaraguan córdoba'),
  ('NGN',100,'₦','Nigerian naira'),
  (NULL,100,'$','Niue dollar'),
  ('KPW',100,'₩','North Korean won'),
  ('NOK',100,'kr','Norwegian krone'),
  ('OMR',1000,'ر.ع.','Omani rial'),
  ('PKR',100,'₨','Pakistani rupee'),
  (NULL,100,'$','Palauan dollar'),
  ('PAB',100,'B/.','Panamanian balboa'),
  ('PGK',100,'K','Papua New Guinean kina'),
  ('PYG',100,'₲','Paraguayan guaraní'),
  ('PEN',100,'S/.','Peruvian nuevo sol'),
  ('PHP',100,'₱','Philippine peso'),
  (NULL,100,'$','Pitcairn Islands dollar'),
  ('PLN',100,'zł','Polish złoty'),
  ('QAR',100,'ر.ق','Qatari riyal'),
  ('RON',100,'lei','Romanian leu'),
  ('RUB',100,'₽','Russian ruble'),
  ('RWF',100,'Fr','Rwandan franc'),
  (NULL,100,'Ptas','Sahrawi peseta'),
  ('SHP',100,'£','Saint Helena pound'),
  ('WST',100,'T','Samoan tālā'),
  ('STD',100,'Db','São Tomé and Príncipe dobra'),
  ('SAR',100,'ر.س','Saudi riyal'),
  ('RSD',100,'дин.','Serbian dinar'),
  ('SCR',100,'₨','Seychellois rupee'),
  ('SLL',100,'Le','Sierra Leonean leone'),
  ('SGD',100,'$','Singapore dollar'),
  ('SBD',100,'$','Solomon Islands dollar'),
  ('SOS',100,'Sh','Somali shilling'),
  (NULL,100,'Sh','Somaliland shilling'),
  ('ZAR',100,'R','South African rand'),
  (NULL,100,'£','South Georgia and the South Sandwich Islands pound'),
  ('KRW',100,'₩','South Korean won'),
  ('SSP',100,'£','South Sudanese pound'),
  ('LKR',100,'රු','Sri Lankan rupee'),
  ('SDG',100,'ج.س.','Sudanese pound'),
  ('SRD',100,'$','Surinamese dollar'),
  ('SZL',100,'L','Swazi lilangeni'),
  ('SEK',100,'kr','Swedish krona'),
  ('CHF',100,'Fr','Swiss franc'),
  ('SYP',100,'£','Syrian pound'),
  ('TJS',100,'ЅМ','Tajikistani somoni'),
  ('TZS',100,'Sh','Tanzanian shilling'),
  ('THB',100,'฿','Thai baht'),
  ('TOP',100,'T$','Tongan paʻanga'),
  ('PRB',100,'р.','Transnistrian ruble'),
  ('TTD',100,'$','Trinidad and Tobago dollar'),
  (NULL,100,'£','Tristan da Cunha pound'),
  ('TND',1000,'د.ت','Tunisian dinar'),
  ('TRY',100,'₺','Turkish lira'),
  ('TMT',100,'m','Turkmenistan manat'),
  (NULL,100,'$','Tuvaluan dollar'),
  ('UGX',100,'Sh','Ugandan shilling'),
  ('UAH',100,'₴','Ukrainian hryvnia'),
  ('AED',100,'د.إ','United Arab Emirates dirham'),
  ('USD',100,'$','United States dollar'),
  ('UYU',100,'$','Uruguayan peso'),
  ('UZS',100,NULL,'Uzbekistani som'),
  ('VUV',NULL,'Vt','Vanuatu vatu'),
  ('VEF',100,'Bs F','Venezuelan bolívar'),
  ('VND',10,'₫','Vietnamese đồng'),
  ('XOF',100,'Fr','West African CFA franc'),
  ('YER',100,'﷼','Yemeni rial'),
  ('ZMW',100,'ZK','Zambian kwacha');