Commits

elifarley  committed adff50b

Added support for multiple repositories

  • Participants
  • Parent commits 871b606

Comments (0)

Files changed (2)

   user = pushy
   password = mypassword
   ## sql is optional. default value below:
-  # sql = CALL push_history_insert(%s, %s, %s, %s)
+  # sql = CALL push_history_insert(%(repo_guid)s, %(user)s, %(via)s, %(host)s, %(changesets)s)
 
 '''
 
     ui.note(_('pushy: user "%s" sent %d changesets (%s)\n' %
         (remote['user'], len(repo) - int(repo[node]), kwargs.get('url', ''))) )
 
-    changesets = _getchangesetids(repo, node)
-    result = _callmysql(ui, remote['user'], remote['via'], remote['host'], changesets)
+    remote['changesets'] = _getchangesetids(repo, node)
+    remote['repo_guid'] = repo[0].hex()
+    # %(repo_guid)s, %(user)s, %(via)s, %(host)s, %(changesets)s
+    result = _callmysql(ui, **remote)
 
     ui.status('pushy: %s\n' % result)
 
 def _getchangesetids(repo, node):
     return [ repo[rev].hex() for rev in xrange(repo[node], len(repo)) ]
 
-def _callmysql(ui, user, via, host, changesets):
+def _callmysql(ui, **sqlparams):
     dbconfig = dict(ui.configitems('pushy.db'))
     dbconfig.setdefault('host', 'localhost')
-    sql = dbconfig.setdefault('sql', "CALL push_history_insert(%s, %s, %s, %s)")
+    sql = dbconfig.setdefault('sql', "CALL push_history_insert(%(repo_guid)s, %(user)s, %(via)s, %(host)s, %(changesets)s)")
 
-    sqlparams = ( user, via, host, ','.join(changesets) )
-    ui.debug('pushy: ' + sql.replace('%s', '"%s"') % sqlparams + '\n')
+    sqlparams['changesets'] = ','.join(sqlparams['changesets'])
+    ui.debug('pushy: ' + sql.replace(', %', '", "%').replace("(%(", '("%(').replace(")s)", ')s")') % sqlparams + '\n')
 
     import MySQLdb
     db = MySQLdb.connect(host=dbconfig['host'], user=dbconfig['user'], passwd=dbconfig['password'], db=dbconfig['dbname']);

File pushy-init.sql

 # Dumping structure for table push_history
 DROP TABLE IF EXISTS `push_history`;
 CREATE TABLE IF NOT EXISTS `push_history` (
-  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `when` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `repo_id` int(10) unsigned NOT NULL,
+  `push_serial` int(10) unsigned NOT NULL,
+  `when` datetime NOT NULL,
   `who` varchar(40) NOT NULL DEFAULT '0',
   `via` varchar(7) NOT NULL,
   `host` varchar(30) DEFAULT NULL,
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+  PRIMARY KEY (`repo_id`,`push_serial`),
+  CONSTRAINT `FK_push_history_push_repo` FOREIGN KEY (`repo_id`) REFERENCES `push_repo` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;
+
+
 
 # Dumping structure for procedure push_history_insert
 DROP PROCEDURE IF EXISTS `push_history_insert`;
 DELIMITER //
-CREATE PROCEDURE `push_history_insert`(IN `in_puser` VARCHAR(40), IN `in_via` VARCHAR(7), IN `in_host` VARCHAR(30), IN `in_items` TEXT)
+CREATE PROCEDURE `push_history_insert`(IN `in_repo_guid` CHAR(40), IN `in_puser` VARCHAR(40), IN `in_via` VARCHAR(7), IN `in_host` VARCHAR(30), IN `in_items` TEXT)
     MODIFIES SQL DATA
-    COMMENT 'Example: CALL push_history_insert(''myloginname'', ''ssh'', ''127.0.0.1'', ''aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'')'
+    COMMENT 'Example: CALL push_history_insert(''<repo-guid>'', ''myloginname'', ''ssh'', ''127.0.0.1'', ''aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'')'
 # Pushy db stored proc
 # Copyright 2012 Elifarley Cruz <elifarley@gmail.com>
 # See https://bitbucket.org/elifarley/pushy
 # GNU General Public License version 2 or any later version.
 BEGIN
 
+DECLARE repo_id INT UNSIGNED DEFAULT NULL;
+DECLARE push_serial INT UNSIGNED DEFAULT 0;
+DECLARE vnow DATETIME DEFAULT NOW();
 DECLARE pos INT DEFAULT 0;
 DECLARE listlen INT DEFAULT 0;
-DECLARE item VARCHAR(40);
-DECLARE phid INT DEFAULT 0;
+DECLARE item VARCHAR(41); /* valid length is 40 */
+DECLARE phid VARCHAR(100) DEFAULT '';
 DECLARE shouldabort INT DEFAULT 0;
-DECLARE msg varchar(200);
+DECLARE msg text;
 DECLARE invalid_cond CONDITION FOR SQLSTATE '22000';
 DECLARE invalid_cs   CONDITION FOR SQLSTATE '22001';
 SET listlen = CHAR_LENGTH(in_items) - CHAR_LENGTH(REPLACE(in_items, ',', ''));
 BEGIN
-
     declare exit handler for invalid_cs set shouldabort=2;
-declare exit handler for not found set shouldabort=1;
+declare continue handler for 1329 BEGIN END;
+/* no data */
+    #declare exit handler for not found set shouldabort=1;
 declare exit handler for sqlwarning set shouldabort=1;
 declare exit handler for sqlexception set shouldabort=1;
-insert into push_history (who, via, host) values (in_puser, in_via, in_host);
+IF LENGTH(in_repo_guid) != 40 THEN
+      SET msg = concat('Invalid repo guid "', in_repo_guid, '"');
+SIGNAL invalid_cs SET MESSAGE_TEXT = msg;
+END IF;
 start transaction;
-SET phid = LAST_INSERT_ID();
+SELECT pr.id, pr.last_serial + 1 INTO repo_id, push_serial FROM push_repo pr WHERE pr.guid = in_repo_guid FOR UPDATE;
+IF repo_id IS NULL THEN
+      INSERT INTO push_repo (guid, last_serial, date_created) VALUES (in_repo_guid, push_serial, vnow);
+SET repo_id = LAST_INSERT_ID();
+END IF;
+SET phid = concat(repo_id, '-', push_serial);
+insert into push_history (repo_id, push_serial, `when`, who, via, host) values (repo_id, push_serial, vnow, in_puser, in_via, in_host);
 WHILE pos <= listlen and shouldabort < 1 DO
       SET pos = pos + 1;
 SET item = SUBSTRING_INDEX(SUBSTRING_INDEX(in_items, ',', pos), ',', -1);
 IF LENGTH(item) != 40 THEN
-        select concat('Invalid changeset "', item, '" for phid ', phid) into msg;
+        SET msg = concat('Invalid changeset "', ifnull(item, '#item#'), '" for phid ', ifnull(phid, '#push id#'));
 SIGNAL invalid_cs SET MESSAGE_TEXT = msg;
 END IF;
-insert into push_x_changeset (push_id, changeset) values (phid, item);
+insert into push_x_changeset (repo_id, push_serial, changeset) values (repo_id, push_serial, item);
 END WHILE;
 END;
 IF shouldabort > 0 THEN
     rollback;
 if msg is null then
-      select concat('Failed to record changeset "', item, '" for user "', in_puser, '" under phid "', phid, '"') into msg;
+      SET msg = concat('Failed to record changeset "', ifnull(item, '#item#'), '" for user "', ifnull(in_puser, '#push user#'), '" under phid "', ifnull(phid, '#push id#'), '"');
 end if;
 SIGNAL invalid_cond SET MESSAGE_TEXT = msg;
 END IF;
 END//
 DELIMITER ;
 
+
+# Dumping structure for table push_repo
+DROP TABLE IF EXISTS `push_repo`;
+CREATE TABLE IF NOT EXISTS `push_repo` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `guid` char(40) NOT NULL,
+  `date_created` datetime NOT NULL,
+  `last_serial` int(11) unsigned NOT NULL DEFAULT '1',
+  `path` varchar(300) DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `guid` (`guid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+
+# Dumping structure for trigger push_repo_update_last_serial
+DROP TRIGGER IF EXISTS `push_repo_update_last_serial`;
+SET SESSION SQL_MODE='';
+DELIMITER //
+CREATE TRIGGER `push_repo_update_last_serial` AFTER INSERT ON `push_history` FOR EACH ROW BEGIN
+  update push_repo set last_serial = new.push_serial where id = new.repo_id;
+END//
+DELIMITER ;
+SET SESSION SQL_MODE=@OLD_SQL_MODE;
+
+
 # Dumping structure for table push_x_changeset
 DROP TABLE IF EXISTS `push_x_changeset`;
 CREATE TABLE IF NOT EXISTS `push_x_changeset` (
-  `push_id` int(10) unsigned NOT NULL,
+  `repo_id` int(40) unsigned NOT NULL,
+  `push_serial` int(10) unsigned NOT NULL,
   `changeset` char(40) NOT NULL,
-  PRIMARY KEY (`changeset`,`push_id`),
+  PRIMARY KEY (`repo_id`,`push_serial`,`changeset`),
   UNIQUE KEY `changeset` (`changeset`),
-  KEY `FK_push_x_changeset_push_history` (`push_id`),
-  CONSTRAINT `FK_push_x_changeset_push_history` FOREIGN KEY (`push_id`) REFERENCES `push_history` (`id`)
+  CONSTRAINT `FK_push_x_changeset_push_history` FOREIGN KEY (`repo_id`, `push_serial`) REFERENCES `push_history` (`repo_id`, `push_serial`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;