[25803] users/jberry/mpwa
source_changes at macosforge.org
source_changes at macosforge.org
Sat Jun 2 13:00:40 PDT 2007
Revision: 25803
http://trac.macosforge.org/projects/macports/changeset/25803
Author: jberry at macports.org
Date: 2007-06-02 13:00:40 -0700 (Sat, 02 Jun 2007)
Log Message:
-----------
mpwa: new changes to schema, of note:
* files are now referenced by file_ref, which provides a new level
of indirection and allows single instance, multiple reference storage
of files, providing more compact storage, especially across minor
changes to port submissions.
* also allows file blobs to be linked into other objects besides
port pkgs, in the future, which might allow, for instance, pictures
to be connected to users.
Modified Paths:
--------------
users/jberry/mpwa/app/models/file_blob.rb
users/jberry/mpwa/app/models/port_pkg.rb
users/jberry/mpwa/app/views/port_pkg/show.rhtml
users/jberry/mpwa/doc/schema.sql
users/jberry/mpwa/lib/mpwa-conf.rb
Added Paths:
-----------
users/jberry/mpwa/app/controllers/file_info_controller.rb
users/jberry/mpwa/app/controllers/file_ref_controller.rb
users/jberry/mpwa/app/helpers/file_infos_helper.rb
users/jberry/mpwa/app/helpers/file_refs_helper.rb
users/jberry/mpwa/app/models/file_info.rb
users/jberry/mpwa/app/models/file_ref.rb
users/jberry/mpwa/app/views/file_info/
users/jberry/mpwa/app/views/file_info/_form.rhtml
users/jberry/mpwa/app/views/file_info/edit.rhtml
users/jberry/mpwa/app/views/file_info/list.rhtml
users/jberry/mpwa/app/views/file_info/new.rhtml
users/jberry/mpwa/app/views/file_info/show.rhtml
users/jberry/mpwa/app/views/file_ref/
users/jberry/mpwa/app/views/file_ref/_form.rhtml
users/jberry/mpwa/app/views/file_ref/edit.rhtml
users/jberry/mpwa/app/views/file_ref/list.rhtml
users/jberry/mpwa/app/views/file_ref/new.rhtml
users/jberry/mpwa/app/views/file_ref/show.rhtml
users/jberry/mpwa/test/fixtures/file_infos.yml
users/jberry/mpwa/test/fixtures/file_refs.yml
users/jberry/mpwa/test/functional/file_infos_controller_test.rb
users/jberry/mpwa/test/functional/file_refs_controller_test.rb
users/jberry/mpwa/test/unit/file_info_test.rb
users/jberry/mpwa/test/unit/file_ref_test.rb
Added: users/jberry/mpwa/app/controllers/file_info_controller.rb
===================================================================
--- users/jberry/mpwa/app/controllers/file_info_controller.rb (rev 0)
+++ users/jberry/mpwa/app/controllers/file_info_controller.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,54 @@
+class FileInfoController < ApplicationController
+ def index
+ list
+ render :action => 'list'
+ end
+
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
+ verify :method => :post, :only => [ :destroy, :create, :update ],
+ :redirect_to => { :action => :list }
+
+ def list
+ @file_info_pages, @file_infos = paginate :file_infos, :per_page => 10
+ end
+
+ def show
+ @file_info = FileInfo.find(params[:id])
+ end
+
+ def new
+ @file_info = FileInfo.new
+ end
+
+ def create
+ @file_info = FileInfo.new(params[:file_info])
+ if @file_info.save
+ flash[:notice] = 'FileInfo was successfully created.'
+ redirect_to :action => 'list'
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @file_info = FileInfo.find(params[:id])
+ end
+
+ def update
+ @file_info = FileInfo.find(params[:id])
+ if @file_info.update_attributes(params[:file_info])
+ flash[:notice] = 'FileInfo was successfully updated.'
+ redirect_to :action => 'show', :id => @file_info
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def destroy
+ FileInfo.find(params[:id]).destroy
+ redirect_to :action => 'list'
+ end
+
+ private :create, :edit, :update, :destroy
+
+end
Added: users/jberry/mpwa/app/controllers/file_ref_controller.rb
===================================================================
--- users/jberry/mpwa/app/controllers/file_ref_controller.rb (rev 0)
+++ users/jberry/mpwa/app/controllers/file_ref_controller.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,66 @@
+class FileRefController < ApplicationController
+ def index
+ list
+ render :action => 'list'
+ end
+
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
+ verify :method => :post, :only => [ :destroy, :create, :update ],
+ :redirect_to => { :action => :list }
+
+ def list
+ @file_ref_pages, @file_refs = paginate :file_refs, :per_page => 10
+ end
+
+ def show
+ @file_ref = FileRef.find(params[:id])
+ end
+
+ def new
+ @file_ref = FileRef.new
+ end
+
+ def create
+ @file_ref = FileRef.new(params[:file_ref])
+ if @file_ref.save
+ flash[:notice] = 'FileRef was successfully created.'
+ redirect_to :action => 'list'
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @file_ref = FileRef.find(params[:id])
+ end
+
+ def update
+ @file_ref = FileRef.find(params[:id])
+ if @file_ref.update_attributes(params[:file_ref])
+ flash[:notice] = 'FileRef was successfully updated.'
+ redirect_to :action => 'show', :id => @file_ref
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def destroy
+ FileRef.find(params[:id]).destroy
+ redirect_to :action => 'list'
+ end
+
+ def emit
+ ref = FileRef.find(params[:id])
+ send_data ref.file_info.data,
+ :filename => ref.file_info.file_path,
+ :type => ref.file_info.mime_type,
+ :disposition => 'inline'
+
+ # Bump download counts for the ref, and for the portpkg too if the file is a portpkg.
+ FileRef.increment_counter('download_count', ref)
+ PortPkg.increment_counter('download_count', ref.port_pkg) if ref.is_port_pkg
+ end
+
+ private :create, :edit, :update, :destroy
+
+end
Added: users/jberry/mpwa/app/helpers/file_infos_helper.rb
===================================================================
--- users/jberry/mpwa/app/helpers/file_infos_helper.rb (rev 0)
+++ users/jberry/mpwa/app/helpers/file_infos_helper.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,2 @@
+module FileInfosHelper
+end
Added: users/jberry/mpwa/app/helpers/file_refs_helper.rb
===================================================================
--- users/jberry/mpwa/app/helpers/file_refs_helper.rb (rev 0)
+++ users/jberry/mpwa/app/helpers/file_refs_helper.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,2 @@
+module FileRefsHelper
+end
Modified: users/jberry/mpwa/app/models/file_blob.rb
===================================================================
--- users/jberry/mpwa/app/models/file_blob.rb 2007-06-02 19:31:25 UTC (rev 25802)
+++ users/jberry/mpwa/app/models/file_blob.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -1,5 +1,7 @@
+require 'file_info'
+
class FileBlob < ActiveRecord::Base
- belongs_to :port_pkg_file
+ belongs_to :file_info
def read(file)
self.data = file.read
Added: users/jberry/mpwa/app/models/file_info.rb
===================================================================
--- users/jberry/mpwa/app/models/file_info.rb (rev 0)
+++ users/jberry/mpwa/app/models/file_info.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,98 @@
+require 'stringio'
+
+require 'file_blob'
+require 'file_ref'
+require 'mpwa-conf'
+
+class FileInfoException < RuntimeError
+end
+
+class FileInfo < ActiveRecord::Base
+ has_many :file_refs
+ #has_many :file_blobs -- we don't use this association to avoid keeping many blobs in memory
+ before_destroy { |f| FileBlob.delete_all "file_info_id = #{f.id}" }
+
+ def FileInfo.mimetype_from_path(path)
+ mimetype = /^([^;]+)(;\w*(.*))?/.match(`#{MPWA::FILETOOL} --mime --brief #{path}`)[1]
+ end
+
+ def read_from_path(path, path_root = nil, options = {})
+ mimetype = options[:mimetype] || FileInfo.mimetype_from_path(path)
+ reported_path = options[:filename] || path_root.nil? ?
+ path.to_s : Pathname.new(path).relative_path_from(path_root).to_s
+
+ File.open(path, "r") { |f| read_from_file(f, :path => reported_path, :mimetype => mimetype) }
+ return self
+ end
+
+ def read_from_file(file, options = {})
+ # Save file meta information
+ self.file_path = options[:path]
+ self.length = 0
+ self.mime_type = options[:mimetype] || 'application/octet-stream'
+
+ # Save so that we get a primary id for the blob associations
+ self.save
+
+ # Create digesters for our digests
+ md5 = Digest::MD5.new
+ sha256 = Digest::SHA256.new
+
+ # Read the file, creating blobs of data as we go
+ buf = ''
+ length = 0
+ seq = 0
+ while (file.read(MPWA::MAX_BLOB_SIZE, buf))
+ # Update the digests
+ md5.update buf
+ sha256.update buf
+
+ # Create a new bob
+ blob = FileBlob.create(:file_info => self, :data => buf, :sequence => seq)
+
+ length += buf.length
+ seq += 1
+ end
+
+ # Finish up
+ self.md5 = md5.hexdigest
+ self.sha256 = sha256.hexdigest
+ self.length = length
+
+ self.save
+ return self
+ end
+
+ def write_to_file(file)
+ # Create a digester so that we can verify the digest
+ digest = Digest::MD5.new
+
+ # Page in the blobs, writing to file as we go
+ length = 0
+ seq = 0
+ while (length < self.length)
+ blob = FileBlob.find(:first, :conditions => "file_info_id=#{self.id} and sequence=#{seq}")
+ raise FileInfoException, "file_info missing segment" if !blob
+
+ buf = blob.data
+ digest.update buf
+
+ file.write(buf)
+ length += buf.length
+
+ seq += 1
+ end
+
+ # Verify the digest
+ raise FileInfoException, "digest mismatch while reading file_info #{self.id}" if digest.hexdigest != self.md5
+ end
+
+ def data()
+ StringIO.open("rw") do |f|
+ write_to_file(f)
+ f.string
+ end
+ end
+
+
+end
Added: users/jberry/mpwa/app/models/file_ref.rb
===================================================================
--- users/jberry/mpwa/app/models/file_ref.rb (rev 0)
+++ users/jberry/mpwa/app/models/file_ref.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,39 @@
+require 'file_info'
+require 'port_pkg'
+
+class FileRef < ActiveRecord::Base
+ belongs_to :file_info
+ belongs_to :port_pkg
+
+ def FileRef.create_from_path(path, path_root, options = {})
+ ref = FileRef.new()
+
+ # Create a new FileInfo object from specfied path
+ new_info = FileInfo.new()
+ new_info.read_from_path(path, path_root, options)
+
+ # If we already had a FileInfo matching the specifics
+ # (path and digests) then use that one, deleting the new
+ existing_info = FileInfo.find_by_md5_and_sha256_and_file_path(
+ new_info.md5, new_info.sha256,
+ new_info.file_path,
+ :conditions => "id != #{new_info.id}")
+ if (existing_info)
+ ref.file_info = existing_info
+ FileInfo.destroy(new_info)
+ else
+ ref.file_info = new_info
+ end
+
+ return ref
+ end
+
+ def <=>(other)
+ if (self.file_info.file_path == other.file_info.file_path)
+ return self.id <=> other.id
+ else
+ return self.file_info.file_path <=> other.file_info.file_path
+ end
+ end
+
+end
Modified: users/jberry/mpwa/app/models/port_pkg.rb
===================================================================
--- users/jberry/mpwa/app/models/port_pkg.rb 2007-06-02 19:31:25 UTC (rev 25802)
+++ users/jberry/mpwa/app/models/port_pkg.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -20,7 +20,8 @@
class PortPkg < ActiveRecord::Base
belongs_to :port
belongs_to :submitter, :class_name => 'Person', :foreign_key => 'submitter_id'
- has_many :files, :class_name => 'PortPkgFile', :dependent => :destroy
+ has_many :file_refs, :dependent => :destroy
+ has_many :file_infos, :through => :file_refs
has_many :variants, :dependent => :destroy
has_and_belongs_to_many :tags
@@ -110,11 +111,14 @@
meta.categories.each { |c| self.add_tag(c) }
# Save unpacked data into a file
- self.files << PortPkgFile.from_path(self, pkgPath, tempDirPath, :mimetype => 'application/vnd.macports.portpkg')
+ portpkg_ref = FileRef.create_from_path(pkgPath, tempDirPath,
+ :mimetype => 'application/vnd.macports.portpkg')
+ portpkg_ref.is_port_pkg = true
+ self.file_refs << portpkg_ref
# Save files from the expanded package
expandedPkgPath.find do |p|
- self.files << PortPkgFile.from_path(self, p, tempDirPath) if p.file?
+ self.file_refs << FileRef.create_from_path(p, tempDirPath) if p.file?
end
# Save the pkg (maybe we shouldn't?)
@@ -132,10 +136,16 @@
return candidates.first
end
- def portpkg_file()
- file_by_path("portpkg.portpkg")
+ def portpkg_file_ref()
+ candidates = self.file_refs.select { |r| r.is_port_pkg }
+ return candidates.first
end
+ def data_file_refs()
+ refs = self.file_refs.select { |r| !r.is_port_pkg }
+ return refs
+ end
+
def has_tag(name)
!self.tags.select { |t| t.name == name }.empty?
end
Added: users/jberry/mpwa/app/views/file_info/_form.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_info/_form.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_info/_form.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,19 @@
+<%= error_messages_for 'file_info' %>
+
+<!--[form:file_info]-->
+<p><label for="file_info_file_path">File path</label><br/>
+<%= text_field 'file_info', 'file_path' %></p>
+
+<p><label for="file_info_length">Length</label><br/>
+<%= text_field 'file_info', 'length' %></p>
+
+<p><label for="file_info_mime_type">Mime type</label><br/>
+<%= text_field 'file_info', 'mime_type' %></p>
+
+<p><label for="file_info_md5">Md5</label><br/>
+<%= text_field 'file_info', 'md5' %></p>
+
+<p><label for="file_info_sha256">Sha256</label><br/>
+<%= text_field 'file_info', 'sha256' %></p>
+<!--[eoform:file_info]-->
+
Added: users/jberry/mpwa/app/views/file_info/edit.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_info/edit.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_info/edit.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,9 @@
+<h1>Editing file_info</h1>
+
+<% form_tag :action => 'update', :id => @file_info do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag 'Edit' %>
+<% end %>
+
+<%= link_to 'Show', :action => 'show', :id => @file_info %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/file_info/list.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_info/list.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_info/list.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,23 @@
+<h1>Listing file_infos</h1>
+
+<table>
+ <tr>
+ <% for column in FileInfo.content_columns %>
+ <th><%= column.human_name %></th>
+ <% end %>
+ </tr>
+
+<% for file_info in @file_infos %>
+ <tr>
+ <% for column in FileInfo.content_columns %>
+ <td><%=h file_info.send(column.name) %></td>
+ <% end %>
+ <td><%= link_to 'Show', :action => 'show', :id => file_info %></td>
+ <td><%= link_to 'Edit', :action => 'edit', :id => file_info %></td>
+ <td><%= link_to 'Destroy', { :action => 'destroy', :id => file_info }, :confirm => 'Are you sure?', :method => :post %></td>
+ </tr>
+<% end %>
+</table>
+
+<%= link_to 'Previous page', { :page => @file_info_pages.current.previous } if @file_info_pages.current.previous %>
+<%= link_to 'Next page', { :page => @file_info_pages.current.next } if @file_info_pages.current.next %>
Added: users/jberry/mpwa/app/views/file_info/new.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_info/new.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_info/new.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,8 @@
+<h1>New file_info</h1>
+
+<% form_tag :action => 'create' do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag "Create" %>
+<% end %>
+
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/file_info/show.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_info/show.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_info/show.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,5 @@
+<% for column in FileInfo.content_columns %>
+<p>
+ <b><%= column.human_name %>:</b> <%=h @file_info.send(column.name) %>
+</p>
+<% end %>
Added: users/jberry/mpwa/app/views/file_ref/_form.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_ref/_form.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_ref/_form.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,7 @@
+<%= error_messages_for 'file_ref' %>
+
+<!--[form:file_ref]-->
+<p><label for="file_ref_is_port_pkg">Is port pkg</label><br/>
+<select id="file_ref_is_port_pkg" name="file_ref[is_port_pkg]"><option value="false">False</option><option value="true">True</option></select></p>
+<!--[eoform:file_ref]-->
+
Added: users/jberry/mpwa/app/views/file_ref/edit.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_ref/edit.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_ref/edit.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,9 @@
+<h1>Editing file_ref</h1>
+
+<% form_tag :action => 'update', :id => @file_ref do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag 'Edit' %>
+<% end %>
+
+<%= link_to 'Show', :action => 'show', :id => @file_ref %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/file_ref/list.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_ref/list.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_ref/list.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,23 @@
+<h1>Listing file_refs</h1>
+
+<table>
+ <tr>
+ <% for column in FileRef.content_columns %>
+ <th><%= column.human_name %></th>
+ <% end %>
+ </tr>
+
+<% for file_ref in @file_refs %>
+ <tr>
+ <% for column in FileRef.content_columns %>
+ <td><%=h file_ref.send(column.name) %></td>
+ <% end %>
+ <td><%= link_to 'Show', :action => 'show', :id => file_ref %></td>
+ <td><%= link_to 'Edit', :action => 'edit', :id => file_ref %></td>
+ <td><%= link_to 'Destroy', { :action => 'destroy', :id => file_ref }, :confirm => 'Are you sure?', :method => :post %></td>
+ </tr>
+<% end %>
+</table>
+
+<%= link_to 'Previous page', { :page => @file_ref_pages.current.previous } if @file_ref_pages.current.previous %>
+<%= link_to 'Next page', { :page => @file_ref_pages.current.next } if @file_ref_pages.current.next %>
Added: users/jberry/mpwa/app/views/file_ref/new.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_ref/new.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_ref/new.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,8 @@
+<h1>New file_ref</h1>
+
+<% form_tag :action => 'create' do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag "Create" %>
+<% end %>
+
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/file_ref/show.rhtml
===================================================================
--- users/jberry/mpwa/app/views/file_ref/show.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/file_ref/show.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,5 @@
+<% for column in FileRef.content_columns %>
+<p>
+ <b><%= column.human_name %>:</b> <%=h @file_ref.send(column.name) %>
+</p>
+<% end %>
Modified: users/jberry/mpwa/app/views/port_pkg/show.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port_pkg/show.rhtml 2007-06-02 19:31:25 UTC (rev 25802)
+++ users/jberry/mpwa/app/views/port_pkg/show.rhtml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -51,15 +51,17 @@
<tr>
<th>Path</th>
<th>Length</th>
- <th>mime-type</th>
+ <th>MIME-type</th>
<th>Download</th>
+ <th>Download Count</th>
</tr>
- <% for file in @port_pkg.files %>
+ <% for ref in @port_pkg.file_refs %>
<tr>
- <td><%= link_to file.file_path, :controller => 'port_pkg_file', :action => 'show', :id => file %></td>
- <td><%=h file.length %></td>
- <td><%=h file.mime_type %></td>
- <td><%= link_to 'download', :controller => 'port_pkg_file', :action => 'emit', :id => file %></td>
+ <td><%= link_to ref.file_info.file_path, :controller => 'file_info', :action => 'show', :id => ref.file_info %></td>
+ <td><%=h ref.file_info.length %></td>
+ <td><%=h ref.file_info.mime_type %></td>
+ <td><%= link_to 'download', :controller => 'file_ref', :action => 'emit', :id => ref %></td>
+ <td><%= ref.download_count %></td>
</tr>
<% end %>
</table>
Modified: users/jberry/mpwa/doc/schema.sql
===================================================================
--- users/jberry/mpwa/doc/schema.sql 2007-06-02 19:31:25 UTC (rev 25802)
+++ users/jberry/mpwa/doc/schema.sql 2007-06-02 20:00:40 UTC (rev 25803)
@@ -7,34 +7,41 @@
user_name varchar(63),
first_name varchar(63),
last_name varchar(63),
- email varchar(63)
+ email varchar(63),
- -- auth_method
- -- auth_token
- -- pub key
+ auth_method varchar(31),
+ auth_token varchar(255),
+
+ public_key text
);
-
+
+
-- Ports represents a port: a piece of software
drop table if exists ports;
create table ports (
id bigint not null primary key auto_increment,
+ -- these fields are duplicated in port_pkgs
name varchar(63),
short_desc text,
long_desc text,
- home_page varchar(255)
+ home_page varchar(255),
+ index name_index(name)
+
-- many-many association for tags through ports_tags
-- many-many association for maintainers through ports_maintainers
);
-
+
+
-- ports_maintainers: many-many association between Maintainers and Ports
drop table if exists maintainers_ports;
create table maintainers_ports (
person_id bigint not null,
port_id bigint not null
);
-
+
+
-- A PortPkg is an instance of build/install rules for a port.
-- There may be many PortPkg for each Port
drop table if exists port_pkgs;
@@ -43,6 +50,11 @@
port_id bigint not null,
+ name varchar(63),
+ short_desc text,
+ long_desc text,
+ home_page varchar(255),
+
submitted_at datetime not null,
submitter_id bigint not null, -- one-one: Person
submitter_notes text,
@@ -53,66 +65,87 @@
votes_for int not null default 0,
votes_against int not null default 0,
- download_count int not null default 0
-
- -- one-many association for variants
- -- many-many association for tags through PkgTagAssoc
- -- many-many association for dependencies through PkgDependencyAssoc
+ download_count int not null default 0,
- -- (note that both pkgs and variants, have dependency relations)
+ index submitted_at_index(submitted_at),
+ index submitter_index(submitter_id),
+ index port_index(port_id)
);
-create index pkg_submit_date on port_pkgs(submitted_at);
-create index pkg_submitter on port_pkgs(submitter_id);
-create index pkg_port_id on port_pkgs(port_id);
-drop table if exists port_pkg_files;
-create table port_pkg_files (
+-- Reference to a file
+-- Currently only supports references from port_pkg, but could
+-- be extended to support references from people (pictures?), etc.
+drop table if exists file_refs;
+create table file_refs (
id bigint not null primary key auto_increment,
- port_pkg_id bigint not null,
+ file_info_id bigint not null,
+ port_pkg_id bigint, -- owned by port_pkg
+ is_port_pkg tinyint(1) not null default 0,
+ download_count int not null default 0,
+
+ index file_index(file_info_id),
+ index port_pkg_index(port_pkg_id)
+);
+
+
+-- FileInfo: main representation of a file, referenced
+-- by other tables through FileRef, with data stored
+-- in one or more FileBlob.
+drop table if exists file_infos;
+create table file_infos (
+ id bigint not null primary key auto_increment,
file_path varchar(2047),
length bigint not null,
mime_type varchar(63),
md5 varchar(32),
sha256 varchar(64),
-
- download_count int not null default 0
+
+ index info_index(file_path(64), md5, sha256)
);
-create index portpkgfile_pkgid on port_pkg_files(port_pkg_id);
drop table if exists file_blobs;
create table file_blobs (
id bigint not null primary key auto_increment,
- port_pkg_file_id bigint not null,
+ file_info_id bigint not null,
sequence int not null,
- data blob
+ data blob,
+
+ index file_index(file_info_id, sequence)
);
-create index fileblog_index on file_blobs(port_pkg_file_id, sequence);
-- A tag which may be attached to various items through Ports_Tags, Port_Pkgs_Tags
drop table if exists tags;
create table tags (
id bigint not null primary key auto_increment,
- name varchar(31)
+ name varchar(31),
+
+ index name_index(name)
);
-create unique index tag_names on tags(name);
+
-- many-many relationship between PortPkg and Tag
-drop table if exists Port_Pkgs_Tags;
-create table Port_Pkgs_Tags (
+drop table if exists port_pkgs_tags;
+create table port_pkgs_tags (
port_pkg_id bigint not null,
- tag_id bigint not null
+ tag_id bigint not null,
+
+ primary key (port_pkg_id, tag_id)
);
+
-- many-many relationship between Port and Tag
drop table if exists ports_tags;
create table ports_tags (
port_id bigint not null,
- tag_id bigint not null
+ tag_id bigint not null,
+
+ primary key (port_id, tag_id)
);
+
-- Variant available to a PortPkg
drop table if exists variants;
create table variants (
@@ -120,13 +153,14 @@
port_pkg_id bigint not null,
name varchar(63),
- description text
+ description text,
- -- many-many association for dependencies through Dependencies_Variants
+ index port_pkg_index(port_pkg_id)
-- conflicts expr?
);
+
-- A dependency onto another port (not complete)
drop table if exists dependencies;
create table dependencies (
@@ -138,18 +172,23 @@
-- maybe we have nullable fields for port, portpkg, porturl, version, revision, etc...
);
+
-- many-one relationship from Dependency to PortPkg
drop table if exists dependencies_port_pkgs;
create table dependencies_port_pkgs (
package_id bigint not null,
- dependency_id bigint not null
+ dependency_id bigint not null,
+
+ primary key (package_id, dependency_id)
);
-- many-one relationship from Variant to Dependency
drop table if exists dependencies_variants;
create table dependencies_variants (
variant_id bigint not null,
- dependency_id bigint not null
+ dependency_id bigint not null,
+
+ primary key (variant_id, dependency_id)
);
@@ -167,7 +206,9 @@
drop table if exists comments_ports;
create table comments_ports (
comment_id bigint not null,
- port_id bigint not null
+ port_id bigint not null,
+
+ primary key (comment_id, port_id)
);
@@ -175,7 +216,9 @@
drop table if exists comments_port_pkgs;
create table comments_port_pkgs (
comment_id bigint not null,
- port_pkg_id bigint not null
+ port_pkg_id bigint not null,
+
+ primary key (comment_id, port_pkg_id)
);
@@ -195,7 +238,9 @@
drop table if exists status_reports_port_pkgs;
create table status_reports_port_pkgs (
status_report_id bigint not null,
- port_pkg_id bigint not null
+ port_pkg_id bigint not null,
+
+ primary key (status_report_id, port_pkg_id)
);
Modified: users/jberry/mpwa/lib/mpwa-conf.rb
===================================================================
--- users/jberry/mpwa/lib/mpwa-conf.rb 2007-06-02 19:31:25 UTC (rev 25802)
+++ users/jberry/mpwa/lib/mpwa-conf.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -1,6 +1,6 @@
class MPWA
FILETOOL = "/usr/bin/file"
- XARTOOL = "/opt/local/bin/xar"
+ XARTOOL = "/usr/local/bin/xar"
PORTTOOL = "/opt/local/bin/port"
MAX_BLOB_SIZE = 1024*64
Added: users/jberry/mpwa/test/fixtures/file_infos.yml
===================================================================
--- users/jberry/mpwa/test/fixtures/file_infos.yml (rev 0)
+++ users/jberry/mpwa/test/fixtures/file_infos.yml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
Added: users/jberry/mpwa/test/fixtures/file_refs.yml
===================================================================
--- users/jberry/mpwa/test/fixtures/file_refs.yml (rev 0)
+++ users/jberry/mpwa/test/fixtures/file_refs.yml 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
Added: users/jberry/mpwa/test/functional/file_infos_controller_test.rb
===================================================================
--- users/jberry/mpwa/test/functional/file_infos_controller_test.rb (rev 0)
+++ users/jberry/mpwa/test/functional/file_infos_controller_test.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'file_infos_controller'
+
+# Re-raise errors caught by the controller.
+class FileInfosController; def rescue_action(e) raise e end; end
+
+class FileInfosControllerTest < Test::Unit::TestCase
+ fixtures :file_infos
+
+ def setup
+ @controller = FileInfosController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @first_id = file_infos(:first).id
+ end
+
+ def test_index
+ get :index
+ assert_response :success
+ assert_template 'list'
+ end
+
+ def test_list
+ get :list
+
+ assert_response :success
+ assert_template 'list'
+
+ assert_not_nil assigns(:file_infos)
+ end
+
+ def test_show
+ get :show, :id => @first_id
+
+ assert_response :success
+ assert_template 'show'
+
+ assert_not_nil assigns(:file_info)
+ assert assigns(:file_info).valid?
+ end
+
+ def test_new
+ get :new
+
+ assert_response :success
+ assert_template 'new'
+
+ assert_not_nil assigns(:file_info)
+ end
+
+ def test_create
+ num_file_infos = FileInfo.count
+
+ post :create, :file_info => {}
+
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_equal num_file_infos + 1, FileInfo.count
+ end
+
+ def test_edit
+ get :edit, :id => @first_id
+
+ assert_response :success
+ assert_template 'edit'
+
+ assert_not_nil assigns(:file_info)
+ assert assigns(:file_info).valid?
+ end
+
+ def test_update
+ post :update, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'show', :id => @first_id
+ end
+
+ def test_destroy
+ assert_nothing_raised {
+ FileInfo.find(@first_id)
+ }
+
+ post :destroy, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_raise(ActiveRecord::RecordNotFound) {
+ FileInfo.find(@first_id)
+ }
+ end
+end
Added: users/jberry/mpwa/test/functional/file_refs_controller_test.rb
===================================================================
--- users/jberry/mpwa/test/functional/file_refs_controller_test.rb (rev 0)
+++ users/jberry/mpwa/test/functional/file_refs_controller_test.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'file_refs_controller'
+
+# Re-raise errors caught by the controller.
+class FileRefsController; def rescue_action(e) raise e end; end
+
+class FileRefsControllerTest < Test::Unit::TestCase
+ fixtures :file_refs
+
+ def setup
+ @controller = FileRefsController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @first_id = file_refs(:first).id
+ end
+
+ def test_index
+ get :index
+ assert_response :success
+ assert_template 'list'
+ end
+
+ def test_list
+ get :list
+
+ assert_response :success
+ assert_template 'list'
+
+ assert_not_nil assigns(:file_refs)
+ end
+
+ def test_show
+ get :show, :id => @first_id
+
+ assert_response :success
+ assert_template 'show'
+
+ assert_not_nil assigns(:file_ref)
+ assert assigns(:file_ref).valid?
+ end
+
+ def test_new
+ get :new
+
+ assert_response :success
+ assert_template 'new'
+
+ assert_not_nil assigns(:file_ref)
+ end
+
+ def test_create
+ num_file_refs = FileRef.count
+
+ post :create, :file_ref => {}
+
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_equal num_file_refs + 1, FileRef.count
+ end
+
+ def test_edit
+ get :edit, :id => @first_id
+
+ assert_response :success
+ assert_template 'edit'
+
+ assert_not_nil assigns(:file_ref)
+ assert assigns(:file_ref).valid?
+ end
+
+ def test_update
+ post :update, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'show', :id => @first_id
+ end
+
+ def test_destroy
+ assert_nothing_raised {
+ FileRef.find(@first_id)
+ }
+
+ post :destroy, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_raise(ActiveRecord::RecordNotFound) {
+ FileRef.find(@first_id)
+ }
+ end
+end
Added: users/jberry/mpwa/test/unit/file_info_test.rb
===================================================================
--- users/jberry/mpwa/test/unit/file_info_test.rb (rev 0)
+++ users/jberry/mpwa/test/unit/file_info_test.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class FileInfoTest < Test::Unit::TestCase
+ fixtures :file_infos
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Added: users/jberry/mpwa/test/unit/file_ref_test.rb
===================================================================
--- users/jberry/mpwa/test/unit/file_ref_test.rb (rev 0)
+++ users/jberry/mpwa/test/unit/file_ref_test.rb 2007-06-02 20:00:40 UTC (rev 25803)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class FileRefTest < Test::Unit::TestCase
+ fixtures :file_refs
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070602/9f40bc56/attachment.html
More information about the macports-changes
mailing list