发明详述
如本申请中所使用的,术语“组件”、“系统”、“接口”等指的是计算机相关的实体,它们可以是硬件、软件(例如,执行中的)和/或固件。例如,组件可以是运行在处理器上的进程、处理器、对象、可执行码、程序、和/或计算机。作为说明,运行在服务器上的应用程序和服务器都可以是组件。一个或多个组件可驻留在一个进程内,且组件可位于一台计算机上和/或分布在两台或更多计算机之间。
本发明参考附图来描述,所有附图中使用相同的参考标号来指代相同的元素。在以下描述中,为解释起见,阐明了众多具体细节以提供对本发明的全面理解。然而,很明显,本发明可以在没有这些具体细节的情况下实施。在其它情况下,以框图形式示出了公知的结构和设备以便于描述本发明。
现在转向附图,图1示出了便于至少基于具有其相应特性的数据模型来操纵数据的系统100。数据模型102可以是至少基于数据库结构的复杂模型,其中定义了项、子项、属性和关系来允许将数据存储系统内的信息表示为复杂类型的实例。数据模型102可利用一组基本构件块来创建和管理丰富的、持久储存的对象以及对象之间的链接。项可被定义为数据模型102内的最小一致性单元,它可被独立地保护、串行化、同步、复制、备份/还原等。项是类型的实例,其中数据模型102中的所有项可被储存在单个全局的项范围中。数据模型102可以基于至少一个项和/或容器结构。此外,数据模型102可以是展示出作为项埋藏在文件中的丰富元数据的存储平台。可以理解,数据模型102可以表示支持上述功能的基于数据库的文件存储系统,其中可实现任何适当的特性和/或属性。此外,数据模型102可表示利用容器分层结构的基于数据库的文件存储系统,其中容器是可包含0个或多个项的项。包含概念经由相关联类内的容器ID属性来实现。仓库也可以是容器,使得仓库可以是物理组织和可管理性单元。另外,仓库表示分层结构内的容器树的根容器。此外,数据模型102可表示数据存储系统,它是定义至少一个持久储存的实体以及每一实体的0个或多个子实体以将信息表示为复杂类型的分层模型的基于数据库的系统。
数据操纵组件104可操纵与数据模型102有关的数据,同时确保与这一数据模型102的特性相关联的数据完整性和稳定性。数据模型102可包括与基于数据库的文件存储系统相关联的任何适当的特性和/或方针。数据操纵组件104可提供对至少一个对象的移动、删除、复制、创建、更新、替换等,同时确保稳定的系统(例如,符合与由数据模型102表示的基于数据库的文件存储系统相关联的任何特性)。例如,数据模型102可表示具有其中用于容器的每一ID都是唯一的特性的基于数据库的文件存储系统。继续该示例,数据操纵组件104可采用任何适当的数据操纵(例如,复制、更新、替换、获取、设置、创建、删除、移动、…),同时实施和/或支持用于容器的ID的唯一性。可以理解,上述功能并不被看做是对本发明的限制,并且可采用涉及数据模型102的任何适当的数据操纵同时维持与其有关的任何适当的特性。此外,可以理解,数据操纵组件104可基于数据模型102来操纵对应于分层结构的数据(例如,利用仓库和容器中的至少一种,…)。
根据本发明的一方面,数据操纵可以通过利用例如应用程序编程接口(API)(未示出)来至少部分地基于来自用户的输入。通过利用API,可实现涉及数据模型102和相应的基于数据库的文件存储系统的交互和/或操纵,同时维持/实施与其相关联的任何适当的特性。可以明白和理解,API可由数据操纵组件104来调用、可以是单独的组件、可被结合到数据操纵组件104中、和/或其任何组合。
系统100还包括接口组件106,它提供了将数据操纵组件104集成到实际上任何操作和/或数据库系统中的各种适配器、连接器、通道、通信路径等。另外,接口组件106可提供允许与数据和数据操纵组件104的交互的各种适配器、连接器、通道、通信路径等。可以理解,尽管接口组件106被结合到数据操纵组件104中,但这一实现并不限于此。例如,接口组件106可以是接收或发送与系统100有关的数据的独立组件。
图2示出了便于在数据存储系统的特性内操纵数据的系统200。数据存储系统202可以是通过至少利用分层结构将数据实例表示为复杂类型的基于数据库的文件存储系统、数据存储系统202可包括被实施以在操纵数据时确保数据存储系统202的特性的至少一个特性。可以理解,数据模型(未示出)可表示数据存储系统202。此外,可在数据存储系统202内定义项、子项、属性和关系,以允许将信息表示为复杂类型的实例。数据存储系统202可以是可描述数据的形状、声明隐含关于数据的某些语义一致性的约束、以及定义数据之间的语义关联的数据模型。数据存储系统202可利用一组基本构件块来创建和管理丰富的、持久存储的对象以及对象之间的链接。
例如,构件块可包括“项(Item)”、“项扩展(ItemExtension)”、“链接(Link)”和“项片段(ItemFragment)”。“项”可被定义为数据存储系统202内的最小一致性单元,它可被独立地保护、串行化、同步、复制、备份/还原等。例如,项可以是最小一致性单元,但是围绕项绘出的边界可包括可由项逻辑地拥有的链接、项扩展以及项片段。由此,项可以是表中的一行,但也可以指该项行及其所有的次要部分。换言之,项可被删除、复制等,同时确保这些操作被原子地应用于项及其所有部分。项是类型的实例,其中数据存储系统202中的所有项可被储存在单个全局的项范围中。“项扩展”是利用实体扩展来扩展的项类型。实体扩展可以在具有相应属性(例如,名称、扩展的项类型、属性声明、…)的模式中定义。可以实现“项扩展”以将可被应用于扩展的项类型的一组属性分组在一起。“链接”是定义两个项实例之间的关联的实体类型,其中链接是定向的(例如,一个项是链接的源,而另一个是链接的目标)。“项片段”是允许在项类型和/或项扩展中声明大集合的实体类型,其中集合的元素可以是实体。可以明白和理解,数据存储系统202可表示提供了数据作为复杂类型实例的表示的任何适当的基于数据库的文件存储系统,且以上描述并不被看做是限制本发明。数据存储系统202可以基本类似于图1所描绘的数据模型102的表示。
数据操纵组件204可提供对数据存储系统202内的数据的操纵,同时实施与这一数据存储系统202相关联的至少一个特性。数据操纵组件204可提供诸如但不限于对数据(例如,由复杂类型的实例来表示)的复制、更新、替换、获取、设置、创建、删除、移动等的操纵。可以理解,数据操纵组件204可以基本类似于图1所描绘的数据操纵组件104。
数据操纵组件204可包括提供根据与数据存储系统202相关联的特性来操纵数据的特定功能的过程组件206。换言之,过程组件206可提供与数据存储系统202有关的操纵技术。例如,过程组件206可包括对数据和/或作为复杂类型实例的数据表示的复制、移动、替换、设置、删除、创建、获取、更新。可以理解,过程组件206可以提供可对数据存储系统202实现的任何适当的数据操纵技术和/或功能。尽管过程组件206被描述为被结合到数据操纵组件204中,但本发明不限于此。过程组件206也可以是独立组件或被结合到数据存储系统202中(例如,可以是数据模型概念的实例化)。
数据操纵组件204还可包括将数据存储系统202的至少一个特性与数据操纵相结合的实施器组件208。如上所述,数据存储系统202可包括可提供关于对这一数据存储系统202内的数据的操纵的引导的任何适当数量的特性。换言之,实施器组件208允许在不破坏与数据存储系统202有关的数据模型约束的情况下对数据存储系统202内的数据进行操纵。可以理解,实施器组件208可被结合到数据操纵组件204中(如图所示)、可以是独立组件、可被结合到数据存储系统202中、以及以上的任意组合。
例如,数据存储系统202可利用项、容器和仓库结构层次(如上所述)。实施器组件208可实现与关联到数据存储系统202的容器ID有关的特性。例如,实施器组件208可提供以下的至少一个:(1)包含仓库中的项的非空项ID的容器ID(例如,这可对以下讨论的操纵函数和/或技术“CreateItem(创建项)”、“CreateComplexItem(创建复杂项)”、“MoveItem(移动项)”和“ReplaceItem(替换项)”实现);(2)容器ID不利用操纵函数和/或技术“UpdateItem(更新项)”(以下讨论)来更新;以及(3)容器ID可经由对“MoveItem”的调用来改变。可以明白和理解,本发明不限于以上函数和/或技术的参考名。
在另一示例中,实施器组件208可结合数据操纵来实现事务语义。实施器组件208可实现以下事务语义:(1)如果没有事务是活动的,则可返回一差错代码并且不处理批;以及(2)试图确认并应用操作。如果确认和应用操作成功,则控制可被返回给调用者,同时带有在由调用者提供事务中未提交操作的效果。如果确认或应用操作失败,则事务失败且引发差错,并且控制可被返回给调用者。失败的事务意味着调用者可发出关于该事务的查询,但是不能提交该事务(例如,提交的调用会导致差错)。可以理解,API请求可原子地成功或完全失败。复杂API可对底层存储表做出至少一个改变,并且可实现一组复杂的一致性和/或完整性测试。此外,可以理解,系统200永不留在非一致和/或无效状态。
图3示出了便于实现与数据存储系统相关联的数据操纵的数据完整性和安全性的系统300。数据存储系统302可以是至少部分地基于数据模型的基于数据库的文件存储系统,其中数据被表示为复杂类型的实例。数据操纵组件304可提供与数据存储系统302相关联的数据操纵。数据操纵组件304可包括可提供涉及操纵数据存储系统302内的数据的至少一个函数和/或技术的过程组件306。此外,数据操纵组件304可包括设立与数据存储系统302有关的至少一个特性和/或方针的实施器组件308,其中这一特性确保对数据操纵实现数据模型约束。可以明白和理解,数据存储系统302、数据操纵组件304、过程组件306以及实施器组件308可以分别基本类似于图3中的数据存储系统202、数据操纵组件204、过程组件206和实施器组件208。
数据操纵组件304可包括便于储存和/或访问与操纵数据存储系统302内的数据相关联的至少一个过程的数据仓库310。例如,数据仓库310可储存可由API利用的过程(例如,代码),其中数据操纵可由用户接收并被调用,同时维护与数据存储系统302相关联的至少一个特性。在另一示例中,数据仓库310可储存与数据存储系统302和/或各种API数据(例如,子例程等)相关联的各种特性。在一个示例中,数据仓库310可以是硬盘驱动器。数据仓库310可以是例如易失性存储器或非易失性存储器,或者可同时包括易失性存储器和非易失性存储器两者。作为说明而非局限,非易失性存储器可包括只读存储器(ROM)、可编程ROM(PROM)、电可编程ROM(EPROM)、电可擦除可编程ROM(EEPROM)或闪存。易失性存储器可包括随机存取存储器(RAM),它用作外部高速缓冲存储器。作为说明而非局限,RAM以多种形式可用,如静态RAM(SRAM)、动态RAM(DRAM)、同步DRAM(SDRAM)、双数据率SDRAM(DDR SDRAM)、增强型SDRAM(ESDRAM)、同步链路DRAM(SLDRAM)、Rambus直接RAM(RDRAM)、直接Rambus动态RAM(DRDRAM)以及Rambus动态RAM(RDRAM)。本系统和方法的数据仓库310旨在包括但不限于这些以及其它任何适当类型的存储器。另外,可以理解,数据仓库310可以是服务器和/或数据库。
数据操纵组件304还可包括向系统300提供至少一个安全属性的安全组件312。例如,安全组件304可利用用户配置文件,使得特定数据操纵函数和/或技术与其相关联。此外,安全组件304可利用诸如但不限于登录、口令、生物测定标记(例如,指纹、视网膜扫描、感应、…)、语音识别等各种安全措施来确保操纵数据的特定实体的完整性和有效型。安全组件312还可采用与数据存储系统302相关联的任何适当的安全属性。换言之,安全组件312可实现安全规章,以实施数据存储系统302的安全约束。
图4示出了便于实现操纵与数据存储系统相关联的数据的API的系统400。数据存储系统402可以是具有与其相关联的至少一个特性的基于数据库的文件存储系统,其中数据存储系统402可由数据模型(未示出)来表示。数据操纵组件404可允许包括但不限于对与数据存储系统402有关的数据的复制、移动、替换、设置、删除、创建、获取、更新的数据操纵。可以理解,数据存储系统402和数据操纵组件404可利用与分别在图3和2中的数据存储系统302、数据存储系统202、数据操纵组件304以及数据操纵组件204基本类似的功能。
数据操纵组件404还可包括允许实体操纵数据存储系统402中的数据的API组件406(此处称为“API 406”)。实体可以是,但不限于,用户、计算机、数据库、…。API 406可接收至少一个用户输入,使得用户输入是涉及对数据存储系统402内的数据的操纵的命令和/或函数。尽管被描绘为结合到数据操纵组件404中,但可以理解,API 406可以是独立的组件、可被结合到数据存储系统402中、和/或其组合。此外,API 406可利用先前讨论的各种组件来提供利用特定过程的数据操纵同时实施与数据存储系统402有关的特性。
图5示出了便于调用在数据存储系统的特性内操纵数据的应用程序编程接口(API)的系统500。数据存储系统502可以是具有至少一个定义特性的基于数据库的文件存储系统,其中数据存储系统502可以至少部分地基于数据模型(未示出)。数据操纵组件504可允许包括但不限于对与数据存储系统502有关的数据的复制、移动、替换、设置、删除、创建、获取、更新的数据操纵。可以理解,数据存储系统502和数据操纵组件504可以基本类似于分别在图4、图3和图2中的数据存储系统402、数据存储系统302、数据存储系统202、数据操纵组件404、数据操纵组件304以及数据操纵组件204。
数据操纵组件504可包括API组件506(称为“API 506”)。API 506可通过执行存储过程来提供数据操纵(例如,仓库内的数据的创建、更新和删除)。API506可允许例如用户实现数据操纵同时确保与数据存储系统502相关联的特性的完整性和/或纯洁度。数据操纵可通过利用例如API 506来至少部分地基于来自用户的输入。通过采用API 506,可实现涉及数据存储系统502的交互和/或操纵,同时维持/实施与其相关联的任何适当的特性。可以明白和理解,API 506可由数据操纵组件504调用、可以是单独的组件、可被结合到数据操纵组件504中、和/或其任意组合。
数据操纵组件504还可包括通过利用确保完整性的适当锁定策略来便于一个或多个应用程序并发地访问数据的锁定组件508。例如,想像这样一种情形,其中有多个请求对一组公共资源的所有权的调用者,它们以由于每一调用者都在等待其它调用者而使没有一个请求能得到满足的方式来做出请求(例如,可发生死锁)。在这一情况下,锁定组件508可允许阻断(例如,锁住)调用者,其中离开这一情况的唯一方法是驱逐调用者之一。为避免这一情况,锁定组件508可支持多个并发调用者,使得复杂的锁定逻辑可确保各个请求自动成功或失败。此外,锁定组件508可检测死锁并对其做出反应。锁定组件508可通过采用经由锁定对数据存储系统的某些部分(例如,仓库)的串行化访问来保持数据一致性。锁定可以在粒度级上完成,其中数据存储系统中受到给定操纵和/或操作影响的资源(例如,仓库)可在这一操纵和/或操作期间锁定。可以理解,不同的操作和/或基本相似的操作可按不同的次序取锁,因此会发生死锁。例如,锁定组件508能以显著的性能损失来避免死锁。此外,锁定组件508可向API 506提供死锁差错代码以通知这一情况。
数据操纵组件504可包括乐观并发性组件510。API 506可利用乐观并发性来向数据存储系统502内的数据应用操纵和/或改变。并发性在至少两个进程试图在基本相似的时刻更新基本相似的数据时发生。乐观并发性组件510利用乐观并发性,其中乐观并发性假定另一进程在基本相似的时刻做出改变的可能性较低,因此它不取锁直到准备好将改变提交给数据存储系统(例如,仓库)。通过采用这一技术,乐观并发性组件510减少了锁定时间并提供了更好的数据库性能。在多个调用者的并发访问导致特定调用者关于仓库状态要被无效的假设的情况下,可检测到该无效假设并且数据改变请求被系统拒绝,直到调用者重新同步了对系统状态的理解并重新提交了请求。
例如,乐观并发性组件510可保持与项相关联的令牌,该令牌随对项的每一次修改而变化。令牌在将数据读入存储器时被传递给调用者。调用者可将令牌作为更新操作的参数向下传回仓库。仓库可将传入的令牌与仓库中的当前令牌值进行比较。如果令牌相等,则写将成功并被实现。然而,如果存储器中调用者的版本是与仓库中的版本不同的值,则这表示项已被另一应用程序修改且写将失败。
在另一示例中,检查由于两个应用程序的并发访问而引起的失败。在以下表中,存在并发地运行在数据存储系统502上的试图修改项的两个应用程序。
时刻 |
应用程序1 |
仓库中的项令牌值 |
应用程序2 |
1 |
空闲 |
1 |
空闲 |
2 |
项被取入存储器。项令牌=1 |
1 |
空闲 |
3 |
空闲 |
1 |
项被取入存储器。项令牌==1 |
4 |
空闲 |
1 |
项在存储器中修改。项令牌==1 |
5 |
空闲 |
1 |
项被提交回仓库。因为存储器中的令牌值匹配仓库中的令牌值,写成功。现在项令牌==2 |
6 |
项在存储器中修改项令牌==1 |
2 |
空闲 |
7 |
项被提交回仓库。出错!存储器中的项令牌(值为1)不匹配仓库令牌值(值为2) |
2 |
空闲 |
API 506可通过返回关于每一创建和/或更新操作的令牌信息来支持这一技术。例如,来自创建函数的输出令牌参数可被命名为“concurrencyToken(并发性令牌)”。API 506也可取令牌信息作为关于更新和/或删除操作的输入参数。传入更新和/或删除操作的令牌信息也可被称为“concurrencyToken”。可以理解,参数既可以是输入参数也可以是输出参数。在输入时,“concurrencyToken”是在对象被读入高速缓存、被创建和/或被更新时接收到的值。如果对于对象没有写,则这可以是仓库中的“期望值”。在输出时,仓库可在成功完成操作之后返回对象的新“concurrencyToken”。
“concurrencyToken”参数可被类型化为BIGINT(例如,64位整型)。可以理解,参数可以是数据库时间戳,然而其值可以不增加。从备份中还原项可导致在过去与时间有关的状态。两个“concurrencyToken”之间的唯一支持的操作是对于相等性和/或不等性的操作。该值也可以在仓库支持的各种视图中可用。视图中的列名是用于项、项扩展、链接和项片段的“LastUpdateLocalTS”。对于安全描述符,列名是“SDLastUpdateLocalTS”。
图6示出了便于调用在数据存储系统的特性内操纵数据的API的系统600。数据存储系统602可以是至少部分地基于数据模型的基于数据库的文件存储系统,其中数据被表示为复杂类型的实例。数据操纵组件604可提供与数据存储系统602相关联的数据操纵。数据操纵组件604可调用API组件606(此处称为“API 606”)。API 606可通过执行存储过程来提供数据操纵(例如,仓库内的数据的创建、更新和删除)。API 606可允许例如用户实现数据操纵同时确保与数据存储系统602相关联的特性的完整性和/或纯洁度。数据存储系统602、数据操纵组件604和API 606可基本类似于分别在图5、4、3和2中的数据存储系统502、402、302和202、数据操纵组件504、404、304和204、API 506、406。
数据操纵组件604可包括可采用API 606利用的至少一个数据结构的数据结构组件608。例如,数据结构组件608可利用各种同义字和/或类属列表类型。在一个示例中,下表可定义同义字和结构化查询语言(SQL)类型,以及列表类型和对应的公共语言运行时间(CLR)。可以理解,下表是示例,且本发明不限于此。
同义字 |
SQL类型 |
[System.Storage.Store].ItemId |
UNIQUEIDENTIFIER |
[System.Storage.Store].LinkId |
UNIQUEIDENTIFIER |
[System.Storage.Sotre].TypeId |
UNIQUEIDENTIFIER |
[System.Storage.Store].CompiledChangeDefinition |
VARBINARY(MAX) |
[System.Storage.Store].FragmentId |
UNIQUEIDENTIFIER |
[System.Storage.Store].Usage |
UNIQUEIDENTIFIER |
[System.Storage.Store].SecurityDescriptor |
VARBINARY(MAX) |
列表类型 |
对应的CLR等效物 |
[System.Storage.Store].AssignmentValueList |
SqlList<[System.Storage.Store].AssignmentValue> |
[System.Storage.Store].ComplexItemList |
SqlList<[System.Storage.Store].ComnplexItem> |
[System.Storage.Store].ItemIdList |
SqlList<[System.Storage.Store].ItemId> |
数据结构组件608可采用改变定义类型。API 606和数据操纵组件604可提供属性粒度级的更新操作和/或修改。通过利用这一技术,调用者可将改变的数据传递给更新方法,同时保持操作的大小与改变的数据的大小成比例。粒度更新可利用ChangeDefinition(改变定义)类型来描述。在数据存储系统602中,对象被持久储存在仓库中,其中表的特定单元,即Contact(联系人)或某一其它复杂类型的所储存的实例具有可能较复杂的属性。可以明白和理解,ChangeDefinition类型可对可应用于结构化对象的一组改变建模。
例如,为更新联系人的名字字段,调用者可创建ChangeDefinition对象的实例、用两个节点(即,描述项类型的一个节点和包含字段名的另一节点)来填充该对象。客户端然后可将ChangeDefinition的已编译版本和相应值的列表中的至少一个传递给UpdateItem方法,该方法在仓库中做出修改。可以理解,可应用基本类似的模式来修改项扩展和/或链接中的字段。
ChangeDefinition实例利用一树结构来对每一属性建模,在该树结构中,树中的每一层可对应于对象类型内的一嵌套属性层。对属性值的改变由叶节点,称为分配节点来表示。分配节点类型可以是assignment(分配)。这些节点可表示对属性的分配,并包含属性名。非叶节点(除根之外)表示作为顶层属性和/或另一嵌套类型属性的成员的嵌套类型。这可被称为遍历节点。遍历节点包含节点列表(分配或遍历)以及由仓库用于实现适当的类型强制转换的类型。遍历节点类型是PathComponent(路径组件)。
数据结构组件608可通过创建遍历和分配节点来构建ChangeDefinition。例如,节点可通过ChangeDefinition来添加,其中ChangeDefinition类具有用于创建节点以及走查树的方法。在一个示例中,ChangeDefinition类不是用户定义类型(UDT)。在另一示例中,以下是定义的分配类型:1)在一深度分配一标量值;2)在一深度分配一嵌套类型实例;以及3)在一深度分配一集合(例如,多集和/或sqlList)。可以明白和理解,标量属性(例如,XML和FileStream(文件流)属性)可被替换。在另一示例中,这些标量属性被部分地更新。一旦树完成,数据结构组件608可利用Compile(编译)方法,该方法可返回可用二进制格式改变的属性的描述(例如,也称为已编译的改变定义)。在一个示例中,值可作为changeDefinition参数被传入Update方法中。
以下是数据结构组件608的一个实现的示例,并且不被看做是对本发明的限制。调用者可负责构建对应于ChangeDefinition树中描述的属性的值列表。当调用者向ChangeDefinition树添加一分配节点时,可向该分配节点分配一索引。该索引可等于n-1(其中n是迄今为止向树的插入次数)。例如,第一个分配节点获得索引0,第二个分配节点获得索引1,依此类推。索引也可被返回给addAssignment(添加分配)的调用者。调用者然后构造包含添加到ChangeDefinition树的属性的值的AssignmentValue(分配值)对象。AssignmentValue然后被添加到AssignmentValueList(分配值列表),使得其在AssignmentValueList中的位置可映射到ChangeDefinition树的分配节点中的索引。分配节点可被添加到ChangeDefinition,且对应的AssignmentValue对象可使用将AssignmentValue对象附加到列表结尾的添加方法添加到AssignmentValueList。所得的AssignmentValueList是对Upade方法的valueList(值列表)参数传入的值。
数据操纵组件604还可包括处理与同数据存储系统602的特性冲突的操作和/或数据操纵相关联的差错的差错组件610。例如,API 606确保当前项域,其中项域是项定义和/或包括相关联的属性、实体和/或子实体的逻辑区域。如果项在项域外部引用(例如,通过项或通过链接、项扩展或项片段),则项如同它不存在那样显现。换言之,可采用差错代码“The item does not exist”(该项不存在)。
差错组件610可调用差错代码。可实现差错代码以表示数据操纵未完成,其中差错代码可对应于描述差错的文本。与对数据存储系统602内的数据的操纵有关的过程和/或操作可返回一整型值,该值可以是函数(例如,删除(delete)、复制(copy)、移动(move)、获取(get)、设置(set)、更新(update)、…)的返回代码。在一个示例中,如果操作成功,则该值可以为0,或者如果操作失败,则该值为非0。每一相应的操纵过程/操作和/或函数可以关联到一差错代码。例如,API 606可返回差错代码而非显示文本。差错代码然后可被链接到对应的文本消息,其中文本消息可在必要时从数据库中的表检索。
图7示出了便于利用API组件来操纵数据存储系统内的数据的系统700。数据存储系统702可以是至少部分地基于数据模型的基于数据库的文件存储系统,其中数据被表示为复杂类型的实例。数据操纵组件704可提供与数据存储系统702相关联的数据操纵,同时确保与数据存储系统702相关联的至少一个特性的实施。数据操纵组件704可调用API组件706(此处称为“API 706”)。API 706可通过执行与接收的用户输入有关的存储过程来提供数据操纵(例如,复制、更新、替换、获取、设置、创建、删除、移动、…)。API 706可接收与数据操纵请求/命令有关的用户输入,其中这一用户输入在确保与数据存储系统702相关联的特性的完整性和/或纯洁度的同时被执行。可以理解,数据存储系统702、数据操纵组件704以及API 706可以基本类似于分别在图6、5、4、3和2中的数据存储系统602、502、402、302和202、数据操纵组件604、504、404、304和204、API 606、506、406。
数据操纵组件704可包括定义允许用户操纵与数据存储系统702相关联的数据而不会使任何数据模型(用于开发数据存储系统702)约束无效的过程和/或操作的API定义组件708。API定义组件708可实现与对数据存储系统702内的数据的操纵有关的任何适当的函数和/或过程。可以理解,以下过程描述是一个示例,且本发明不限于此。此外,以下过程参考名、功能、属性和描述不是对本发明的限制。
API定义组件708可利用过程来创建数据存储系统702内的项,更具体地是创建数据存储系统702内的仓库中的项。例如,下表提供了与创建项过程相关联的参数。
名称 |
方向 |
类型 |
描述 |
Item |
入 |
[System.Storage.Store].Item |
要储存的项 |
namespaceName |
入 |
NVARchar(255) |
数据存储系统名字空间中储存并使用的名字空间名称。该名称必须为非空,并且返回非空串或差错。 |
securityDescriptor |
入 |
[System.Storage.Store].SecurityDescriptor |
直接应用于新创建的项的安全描述符。它是安全描述符的二进 |
|
|
|
制形式。该参数是可任选的,且可为空。在这一情况下,安全性从包含项继承。默认值为空。 |
promotionStatus |
入 |
INTEGER |
要对项储存的提升值。如果值为非空且项不是根文件后备项(例如,isFileBacked!=TRUE),则返回差错。如果该参数被设为空且项是根文件后备项,则设置STALE的值。默认值为空。 |
isFileBacked |
入 |
BIT |
指定项是否是文件后备项。如果isFileBacked被设为TRUE,则与该项相关联的isFileBacked位被设为TRUE且创建0长度文件流并将其与该项相关联。如果项的任一祖先是文件后备项,则返回差错。默认值为空。 |
concurrencyToken |
出 |
BIGINT |
当过程返回时,该变量包含与该项的创建相关联的并发性令牌。默认值为空。 |
isGhost |
入 |
BIT |
指定项是否应被制作重影。该参数对于不被准许使用该参数的调用者应为空。如果isGhost被设为TRUE且该项不是根文件后备项,则返回差错。默认值为空。 |
itemSyncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
itemSyncMetadata |
入 |
[System.Storage.Store].ItemSyncMetadata |
如果调用者没有同步则必须为空。默认值为空。 |
如上所述,创建项过程至少部分地基于确保与数据存储系统702有关的约束,可具有与其相关联的各种差错代码。这些差错代码可以是任何适当的格式,其中代码可表示描述相应差错的文本消息。例如,当用户试图创建文件后备文件夹时,可生成差错代码。在另一示例中,如果类型为类属文件的项不是文件后备的,则可生成差错代码。
继续创建项的示例过程,每一项具有称为ContainerId(容器Id)的属性,它是容器项的ItemId(项Id)。容器项必须已经存在于仓库中且可从客户端的连接点达到。如果调用者未提供关于项的CreationTime(创建时间)(例如,提供了空值),则仓库将CreationTime设为当前时间。如果调用者未提供关于项的LastModificationtime(最后修改时间)(例如,提供了空值),则仓库将LastModificationTime设为当前时间。如果未提供这两个值,则仓库将提供item.CreationTime,且所生成的item.LastModificationTime将基本类似。
在另一示例中,API定义组件708可采用SecurityDescriptor(安全描述符)。包括可任选的SecurityDescriptor满足了对客户端能够自动创建新项且明确地设置安全性和验证参数的要求。可以理解,SecurityDescriptor可结合上述安全组件(未示出)来工作。此外,API定义组件708可定义墓碑项的实现。如果在仓库中存在具有与传入过程的项id完全相同的项id的墓碑项,则过程不会失败。墓碑项将被复活,且传入对CreateItem的这一调用的新数据将被放入复活的项中。
如上所述,返回concurrencyToken以允许客户端使用关于对项的后继更新的乐观并发性检测。所返回的concurrencyToken用于项的令牌。在另一示例中,当文件系统代理调用CreateItem时,API组件706将不生成监察。该调用将在用户的上下文中做出(例如,exec_as_token),并且将在API 706中完成访问监察。对该事件的文件系统(例如,传统文件存储系统,其中基于位的系统结合操作系统采用具有类似的位大小的API)监察将由文件系统代理生成。此外,API定义组件708可提供与文件后备项有关的各种实施。例如,如果项是文件后备项(例如,isFileBacked标志被设为真),则以下适用:1)FileBackedItem(文件后备项)不能被包含在另一文件后备项树中(例如,对于父项,EntityState.RootFileBackedItemId应为空);以及2)仅被声明为“CompoundItem(复合项)”类型的项可以是文件后备的。
API定义组件708可实现创建至少一个复杂项的过程。该过程可以在与数据存储系统702相关联的仓库中创建多个项。可以理解,API定义组件708可创建一组项扩展以及与每一项的一组链接。类型ComplexItem(复杂项)是不可变UDT。它本质上是传递与操作/过程相关联的数据的容器。以下是ComplexItem的示例定义。
public class ComplexItem
{
Public ComplexItem( Item item,
SqlInt32PromotionStatus,
SqlBoolean isFileBakced,
SqlString namespaceName,
SqlBoolean isGhost,
SyncEntityVersion syncInfo,
item SyncMetadata syncMetadata);
public void AddLink( Link link,
SyncEntityInformation syncInfo,
LinkSyncMetadata syncMetadata);
public void AddItemExtension( ItemExtension itemExtension,
SyncEntityVersion syncInfo);
public void AddItemFragment( ItemFragment itemFragment,
SyncEntityVersion syncInfo);
}
此外,下表提供了与创建复杂项过程相关联的参数的示例。
名称 |
方向 |
类型 |
描述 |
ComplexItems |
入 |
[System.Storage.Store].ComplexItemList |
一个或多个ComplexItem实例的列表 |
securityDescriptor |
入 |
[System.Storage.Store].SecurityDescriptor |
直接应用于所有新创建的项的安全描述符。串是安全描述符的二进制形式。该参数是可任选的,且可为空。在该情况下,对所有项的安全性从包含项的源 |
|
|
|
继承。默认值为空。 |
concurrencyToken |
出 |
BIGINT |
当该过程返回时,concurrencyToken包含与所创建的所有项、链接和项扩展的创建相关联的值。默认值为空。 |
可以理解,API定义组件708可提供以下功能。事务语义使得所有项被原子地添加。如果在函数期间有任何失败,则没有一个复杂项被插入到仓库中。如果complexItems列表为空,则操作为空操作并返回成功。如果在仓库中存在具有与传入该过程的任一项ID相同的项ID的墓碑项,则该过程失败。项扩展列表可为空或者是具有0个或多个实体的非空列表。链接列表可为空或者是具有0个或多个实体的非空列表。项片段列表可为空或者是具有0个或多个实体的非空列表。返回concurrencyToken以允许客户端使用关于后继更新的乐观并发性检测。concurrencyToken值将应用于作为这一操作的结果创建的所有项、链接和项扩展。关于文件后备项,可以下适用:1)FileBackedItem不能被包含在另一文件后备项树中(例如,对父项,EntityState.RootFileBackedItemId应为空);以及2)仅被声明为“CompoundItem”类型的项可以是文件后备的。
API定义组件708可实现在数据存储系统702的仓库内创建链接的过程。例如,下表可描绘与用于创建链接的过程相关联的各种参数。
名称 |
方向 |
类型 |
描述 |
link |
入 |
[System.Storage.Store].Link |
链接 |
concurrencyToken |
出 |
BIGINT |
当该过程返回时,concurrencyToken包含与该链接的创建相关联的值。默认值为空。 |
syncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
syncMetadata |
入 |
[System.Storage.Store]. |
如果调用者没有同步则必须为 |
|
|
LinkSyncMetadata |
空。默认值为空。 |
可以理解,API定义组件708确保了与数据存储系统702相关联的各种特性。例如,目标项id可指向正确类型(如在该链接类型的模式中指定的)的有效项,和/或目标项id必须为空。CreateLink(创建链接)可用于在现有的数据存储系统702的项之间创建一个链接。可以理解,如果在仓库中存在具有与传入该过程的链接id和源项id基本类似的链接id和源项id的墓碑链接,则该过程不会失败。墓碑链接可被复活,且传入对CreateLink的这一调用的新数据将被放入复活的链接中。另外,可返回concurrencyToken来允许客户端使用关于对该链接的后继更新的乐观并发性检测。
API定义组件708可采用在仓库内创建项扩展的过程。例如,下表可描绘与用于创建项扩展的过程相关联的各种参数。
名称 |
方向 |
类型 |
描述 |
itemExtention |
入 |
[System.Storage.Store].ItemExtension |
扩展项扩展的UDT的实例。 |
itemId |
入 |
[System.Storage.Store].ItemId |
ItemExtension要关联到的项的项id。 |
concurrencyToken |
出 |
BIGINT |
当该过程返回concurrencyToken时,它包含与该项扩展的创建相关联的值。默认值为空。 |
syncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
可返回以上利用的concurrencyToken以允许客户端利用关于对该项扩展的后继更新的乐观并发性检测。
API定义组件708可调用修改仓库内的项的过程,其中仓库是与数据存储系统702有关的持久储存的数据。下表是对应于修改项过程的参数和描述的一个示例。
itemId |
入 |
[System.Storage.Store].ItemId |
要更新的项的Id |
compiledChangeDefinition |
入 |
[System.Storage.Store].CompiledChangeDefinition |
要修改的项中的属性的描述。 |
valueList |
入 |
[System.Storage.Store].AssignmentValueList |
要应用于ChangeDefinition中的属性的值集。 |
promotionStatus |
入 |
INTEGER |
要对项储存的提升值。如果项不是文件后备项则忽略该参数。如果传入空则值保持不变。 |
concurrencyToken |
出入 |
BIGINT |
在输入时concurrencyToken是项的期望值。当过程返回concurrencyToken时,它包含与该项的更新相关联的值。如果输入值为空,则不完成任何检查。仍返回新的concurrencyToken。默认值为空。 |
syncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
syncMetadata |
入 |
[System.Storage.Store].ItemSyncMetadata |
如果调用者没有同步则必须为空。默认值为空。 |
API定义组件708可调用修改仓库中的链接的过程。下表是对应于修改链接过程的参数和描述的一个示例。
名称 |
方向 |
类型 |
描述 |
sourceItemId |
入 |
[System.Storage.Store].ItemId |
链接的源项的id |
linkId |
入 |
[System.Storage.Store].TypeId |
要更新的链接的id |
compiledChangeDefinition |
入 |
[System.Storage.Store].CompiledChangeDefinition |
要修改的项中的属性的描述。 |
valueList |
入 |
[System.Storage.Store].AssignmentValueList |
要应用于ChangeDefinition中的属性的值集。 |
concurrencyToken |
出入 |
BIGINT |
在输入时concurrencyToken是链接的期望值。当过程返回concurrencyToken时,它包含与该链接的更新相关联的值。如果输入值为空,则不完成任何检查。仍返回新的concurrencyToken。默认值为空。 |
syncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
syncMetadata |
入 |
[System.Storage.Store].ItemSyncMetadata |
如果调用者没有同步则必须为空。默认值为空。 |
链接的源是不可变的,并且不能通过使用存储过程来改变。链接的目标是可变的,并且可通过调用UpdateLink(更新链接)来改变。目标项id的类型可以为空或非空。如果为非空,则它可指向存在于仓库中的项,并且它可匹配链接上声明的类型。
另外,API定义组件708可修改仓库中的项扩展。下表是由API定义组件708使用的过程的一个示例,并且示出了与其相关联的各种属性和/或描述。
名称 |
方向 |
类型 |
描述 |
itemId |
入 |
[System.Storage.Store].ItemId |
目标项扩展关联到的项的id |
typeId |
入 |
[System.Storage.Store].LinkId |
项扩展的类型id |
compiledChangeDefinition |
入 |
[System.Storage.Store].CompiledChangeDefinition |
描述了项扩展中的哪些属性将被修改。 |
valueList |
入 |
[System.Storage.Store].AssignmentValueList |
要应用于ChangeDefinition中的属性的值集。 |
concurrencyToken |
出入 |
BIGINT |
在输入时concurrencyToken是扩展的期望值。当过程返回concurrencyToken时,它包含与该项扩展的更新相关联的值。如果输入值为空,则不完成任何检查。仍返回新的concurrencyToken。默认值为空。 |
syncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
此外,API定义组件708可调用API 706的允许在仓库内删除项的过程。以下是具有从仓库中删除项的过程的示例参数和描述的表。
itemId |
入 |
[System.Storage.Store].ItemId |
要删除的项的项id |
concurrencyToken |
入 |
BIGINT |
该项的并发性令牌的期望值。如果值为空,则不完成检查。默认值为空。 |
deletionUtc |
入 |
DATETIME |
如果调用者没有同步则必须为空。默认值为空。 |
syncVersion |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
在未找到项的情况下,该过程将返回成功。仓库中以该项为目标的任何链接都可将TargetItemId属性设为空。无论调用者对链接所具有的实际许可是什么,将TargetItemId设为空都可成功。当删除一项时,可删除以该项为源的链接、与该项相关联的项扩展和项片段。如果项没有子项(例如,不存在容器id等于项id的项),则删除可以成功。在一个示例中,没有方法来强制对项树的级联删除。这只能由调用者实现。如果项id是墓碑的,则不论concurrencyToken/LastUpdateTS值的状态是什么都返回成功。如果concurrencyToken不匹配且项不是墓碑,则可返回差错代码。文件系统代理可在其自己的上下文中调用DeleteItem。在API 706中不完成任何访问检查或监察。
API定义组件708可调用删除仓库中的链接的过程。下表是对应于删除链接过程的参数和描述的一个示例。
名称 |
方向 |
类型 |
描述 |
sourceItemId |
入 |
[System.Storage.Store].ItemId |
要删除的链接的源项的项id |
linkId |
入 |
[System.Storage.Store].LinkId |
要删除的链接的id |
concurrencyToken |
入 |
BIGINT |
该链接的并发性令牌的期望值。如果值为空,则不完成检查。默认值为空。 |
deletionUtc |
入 |
DATETIME |
如果调用者没有同步则必须为空。默认值为空。 |
syncVersion |
入 |
[System.Storage.Store].SyncVersion |
如果调用者没有同步则必须为空。默认值为空。 |
API定义组件708可采用删除数据存储系统702内的仓库中的项扩展的过程。下表是对应于用于本发明的删除项扩展过程的参数和描述的一个示例。
名称 |
方向 |
类型 |
描述 |
itemId |
入 |
[System.Storage.Store].ItemId |
目标项扩展关联到的项的id |
typeId |
入 |
[System.Storage.Store].TypeId |
项扩展的类型id |
concurrencyToken |
入 |
BIGINT |
该项扩展的并发性令牌的期望值。如果值为空,则不完成检查。默认值为空。 |
deletionUtc |
入 |
DATETIME |
如果调用者没有同步则必须为空。默认值为空。 |
syncVersion |
入 |
[System.Storage.Store].SyncVersion |
如果调用者没有同步则必须为空。默认值为空。 |
另外,API定义组件708可采用创建仓库中的项片段的过程。下表是对应于允许用户创建项片段的过程的参数和描述的一个示例。
名称 |
方向 |
类型 |
描述 |
itemFragment |
入 |
[System.Storage.Store].ItemFragment |
要创建的项片段。项片段的片段id被储存在udt内。 |
concurrencyToken |
出 |
BIGINT |
当过程返回concurrencyToken时,它包含与该项片段的创建相关联的值。默认值为空。 |
syncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
API定义组件708可调用修改仓库中的项片段的过程。这一存储过程可对每一类型生成,使得ItemFragment属性的类型名称和名称将被包含在存储过程的名称中。为更清晰起见,参考如上所述的“CreateItemFragment(创建项片段)”。下表是对应于修改仓库中的项片段的参数和描述的一个示例。
名称 |
方向 |
类型 |
描述 |
itemId |
入 |
[System.Storage.Store].ItemId |
要更新的项片段的项的id |
setId |
入 |
[System.Storage.Store].SetId |
要更新的项片段属性的标识符 |
fragmentId |
入 |
[System.Storage.Store].FragmentId |
要更新的片段的片段id |
compiledChangeDefinition |
入 |
[System.Storage.Store].CompiledChangeDefinition |
要修改的项片段属性的描述。 |
valueList |
入 |
[System.Storage.Store].AssignmentValueList |
要应用于ChangeDefinition中的属性的值集。 |
concurrencyToken |
出入 |
BIGINT |
在输入时concurrencyToken是项片段的期望值。当过程返回时,concurrencyToken包含与该项片段的更新相关联的值。如果输入值为空,则不完成任何检查。仍返回新的concurrencyToken。默认值为空。 |
syncInfo |
入 |
[System.Storage |
如果调用者没有同步则必须 |
|
|
.Store].SyncEntityVersion |
为空。默认值为空。 |
API定义组件708可定义和/或实现删除仓库中的项片段的过程。以下是描绘了各种参数的表,作为删除数据存储系统702内的项片段的过程的一个示例。
名称 |
方向 |
类型 |
描述 |
itemId |
入 |
[System.Storage.Store].ItemId |
要删除的项片段的源项的项id |
setId |
入 |
[System.Storage.Store].SetId |
要删除的项片段属性的标识符 |
fragmentId |
入 |
[System.Storage.Store].FragmentId |
要更新的片段的片段id |
concurrencyToken |
入 |
BIGINT |
该项片段的并发性令牌的期望值。如果值为空,则不完成检查。默认值为空。 |
deletionUtc |
入 |
DATETIME |
如果调用者没有同步则必须为空。默认值为空。 |
syncVersion |
入 |
[System.Storage.Store].SyncVersion |
如果调用者没有同步则必须为空。默认值为空。 |
此外,API定义组件708可采用获得项的安全描述符的过程。下表是与获得数据存储系统702内的项的安全描述符的过程相关联的各种参数的一个示例。
名称 |
方向 |
类型 |
描述 |
itemId |
入 |
[System.Storage.Store].ItemId |
应检索其安全描述符的项的id |
securityInfoFlags |
入 |
INTEGER |
指示要返回安全描述符的哪些部分的一组标志 |
securityDescriptor |
出 |
[System.Storage.Store]. |
安全描述符 |
|
|
SecurityDescriptor |
|
concurrencyToken |
出 |
BIGINT |
当过程返回时该变量包含与该安全描述符的更新相关联的并发性令牌值。默认值为空。 |
返回concurrencyToken以允许客户端使用关于对安全描述符的后继更新的乐观并发性检测。concurrencyToken可以与安全描述符相关联。在一个示例中,用于安全描述符的concurrencyToken不与对应于itemId的项的concurrencyToken值有关。文件系统代理可在其自己的上下文中调用GetItemSecurity(获取项安全性)。
API定义组件708可设置仓库中的项的安全描述符。下表是由API 706用于设置安全描述符的过程的一个示例,并示出了与其相关联的各种属性和/或描述。
名称 |
方向 |
类型 |
描述 |
itemId |
入 |
[System.Storage.Store].ItemId |
应检索其安全描述符的项的id |
securityInfoFlags |
入 |
INTEGER |
指示要更新安全描述符的哪些部分的一组标志 |
securityDescriptor |
入 |
[System.Storage.Store].SecurityDescriptor |
安全描述符 |
concurrencyToken |
入出 |
BIGINT |
在输入时这是安全描述符的并发性令牌的期望值。当过程返回时该变量包含与该安全描述符的更新相关联的并发性令牌值。如果输入值为空则不完成任何检查。仍返回新的concurrencyToken值。默认值为空。 |
API定义组件708可采用将项从一个容器移至另一个和/或改变项的namespaceName的过程。下表是与这一过程相关联的各种参数的一个示例。
名称 |
方向 |
类型 |
描述 |
itemId |
入 |
[System.Storage.Store].ItemId |
要移动的项的项id |
newContainerId |
入 |
[System.Storage.Store].ItemId |
要将项移至的容器的id。如果传递了空,则容器id保持不变 |
namespaceName |
入 |
NVARchar(255) |
namespaceName名称的值。如果传递了空则名称保持不变。传入空串是出错的。*参见注释一节以获得关于类型的实际声明长度的细节。 |
concurrencyToken |
入出 |
BIGINT |
该项的并发性令牌的期望值。如果值为空则不完成任何检查。默认值为空。 |
如果要移动的项或者新容器中的任一个不能从当前连接点达到,则该过程可返回差错。如果具有相同名称的项已存在于目标容器中,则该操作失败。有三种有效的方式来使用这一函数。这些使用在下表中捕捉:
namespaceName |
newContainerId |
结果 |
空 |
空 |
出错 |
空 |
非空 |
移动项但保持相同的namespaceName |
非空 |
空 |
不移动项,且改变namespaceName |
非空 |
非空 |
将项移至新容器并改变namespaceName |
不论如何调用MoveItem(例如,移动项和/或对项重命名),都更新项的LastUpdateTS值(如concurrencyToken中返回的)。文件系统代理可在用户上下文中调用MoveItem。对重命名的文件/目录不进行访问检查或监察。在新父项上完成的访问检查和监察确定用户是否具有访问来将项移至新目的地。
API定义组件708可采用用不同类型的新项来替换项的过程。下表是与这一过程相关联的各种参数的一个示例。
名称 |
方向 |
类型 |
描述 |
newItem |
入 |
[System.Storage.Store].ItemId Item |
要替换仓库中的现有项的项 |
deleteItemOwnedContent |
入 |
BIT |
如果该参数为真则将删除拥有内容的所有项(以该项为源的链接、项扩展、附加到该项的文件流)。 |
concurrencyToken |
出入 |
BIGINT |
在输入时concurrencyToken是项的期望值。当过程返回时,concurrencyToken包含与该项的更新相关联的值。如果输入值为空,则不完成任何检查。仍返回新的concurrencyToken。默认值为空。 |
syncInfo |
入 |
[System.Storage.Store].SyncEntityVersion |
如果调用者没有同步则必须为空。默认值为空。 |
ReplaceItem(替换项)操作可用于用另一Item对象来替换一个Item对象。这些对象可被称为OldItem(旧项)和NewItem(新项)。OldItem和NewItem可具有相同的ItemId,但可具有不同的类型。例如,其中使用这一操作的一种应用是属性提升。以下描述可以与ReplaceItem操作相关联:1)容器ID不能改变(为获得这一功能,调用者必须调用MoveItem);2)现有的namespaceName不改变;3)如果项是文件后备的,则总是删除以要替换的项为源的所有项;4)如果替换项操作将导致以该项为目标的链接无效(由于目标类型约束不再有效),则ReplaceItem失败;5)如果替换项操作将导致以该项为源的链接无效(由于源类型约束不再有效),则ReplaceItem失败;6)新项的改变单元都被设为默认值。可以有至少两个异常。如果项参与同步,则可将ChangeInformation.SyncInformation.CreationSyncVersion值从旧项延续至新项。另外,如果项参与同步且是文件后备的,则用于文件流的改变单元从旧项延续至新项;7)必须指定所有基于文件的属性。与CreateItem不同,如果File属性不由用户设置,则没有File属性从父文件夹的继承;8)对文件后备项,不修改任何文件流数据,除非指定了DeleteItemOwnedContent标志(见下表);
OldItem |
NewItem类型 |
行为 |
非文件后备项 |
文件后备项 |
不允许;ReplaceItem失败(返回差错代码)。 |
文件后备项 |
文件后备项 |
保留旧文件流(除非由标志DeleteEmbeddedContent(删除嵌入的内容)覆盖)。如果项参与同步,则对应于文件流的改变单元值从旧项延续至新项。 |
文件后备项 |
非文件后备项 |
不允许;ReplaceItem失败(返回出错代码)。 |
非文件后备项 |
非文件后备项 |
无特殊行为。 |
以及9)ReplaceItem不允许项从类属项类型切换到复合项类型,反之亦然(见下表)。
OldItem |
NewItem类型 |
行为 |
类属 |
类属 |
允许 |
复合 |
复合 |
允许 |
类属 |
复合 |
不允许(返回差错代码) |
复合 |
类属 |
不允许(返回差错代码) |
图8示出了采用智能以便于至少部分地基于具有相应特性的数据模型来操纵数据的系统800。系统800可包括数据存储系统802(可由数据模型表示来表示)、数据操纵组件804、以及接口106,它们都可基本类似于前面的图中所描述的相应组件。系统800还包括智能组件806。智能组件806可由数据操纵组件804利用以便于根据与数据存储系统802相关联的至少一个特性来操纵数据(例如,复制、更新、替换、获取、设置、创建、删除、移动、…)。例如,智能组件806可用于分析与数据存储系统802相关联的特性,和/或确保与数据存储系统802有关的特性的完整性。
可以理解,智能组件806能够从一组通过事件和/或数据捕捉的观察中推出或推断系统、环境和/或用户的状态。例如,推断可用于标识特定的上下文或动作,或可生成状态的概率分布。推断可以是概率性的-即,基于数据和事件的考虑计算感兴趣的状态的概率分布。推断也可以指用于从一组事件和/或数据组成更高级事件的技术。这类推断导致从一组观察的事件和/或储存的事件数据构造新的事件或动作,无论事件是否在相邻的时间上相关,也无论事件和数据是来自一个还是若干个事件和数据源。可采用各种分类(显式和/或隐式训练的)方案和/或系统(例如,支持矢量机、神经网络、专家系统、贝叶斯信任网络、模糊逻辑、数据融合引擎…)来执行关于本发明的自动化和/或推断的动作。
分类器是将输入属性矢量x=(x1,x2,x3,x4,xn)映射到该输入属于一个类的置信度的函数,即f(x)=confidence(class)。这一分类可采用基于概率和/或基于统计的分析(例如,分解成分析效用和成本)来预测或推断用户期望自动执行的动作。支持矢量机(SVM)是可采用的分类器的一个示例。SVM通过找出可能输入空间中的超曲面来操作,其中,超曲面试图将触发准则从非触发事件中分离出来。直观上,这使得分类对于接近但不等同于训练数据的测试数据正确。可采用其它定向和非定向模型分类方法,包括,例如,单纯贝叶斯、贝叶斯网络、决策树、神经网络、模糊逻辑模型以及提供不同独立性模式的概率分类模型。此处所使用的分类也包括用于开发优先级模型的统计回归。
图9-10示出了根据本发明的方法。为解释简明起见,方法被描绘和描述为一系列动作。可以理解和明白,本发明不受所示的动作和/或动作次序的限制,例如,动作可按各种次序和/或并发地发生,并且可以与此处未呈现和描述的其它动作一起发生。此外,并非所有示出的动作都是实现根据本发明的方法所必需的。另外,本领域的技术人员可以理解和明白,方法可经由状态图或事件替代地被表示为一系列相关状态。
图9示出了便于调用基于数据库的系统内的数据操纵同时实施至少一个模型约束的方法900。在参考标号902处,可利用数据模型来表示数据存储系统。数据模型可以是至少部分地基于数据结构的复杂模型,其中定义了项、子项、属性和关系以允许将数据存储系统内的信息表示为复杂类型的实例。数据模型可利用一组基本构件块来创建和管理丰富的、持久储存的对象以及对象之间的链接。可以理解,数据模型可包括反映在所表示的数据存储系统的结构和/或功能上的至少一个特性。换言之,数据模型可包含可被实施以确保数据模型、数据存储系统以及与其相关联的数据的完整性的约束。
在参考标号904处,可确定与数据存储系统(基于数据模型)相关联的特性。特性例如可包括方针、限制、蓝图等,它们根据这些特性提供了数据存储系统。通过采用这些特性,可确保相应数据模型的完整性和准确性。在参考标号906处,可通过实现至少一个过程来调用数据操纵。在提供与数据存储系统有关的任何适当的数据操纵时,实施这一数据存储系统的特性以提供稳定环境。在一个示例中,可采用API来允许结合数据存储系统的任何适当的数据操纵。例如,API可由用户利用,其中用户可修改数据。可以理解,数据操纵可包括但不限于,复制、更新、替换、获取、设置、创建、删除、移动等。例如,数据存储系统可包括容器分层系统,其中这一特性在用于操纵数据存储系统内的数据的任何过程期间实施。
图10示出了用于至少部分地基于实施了相应特性的数据模型来操纵数据的方法1000。在参考标号1002处,可利用数据模型来表示数据存储系统。数据存储系统可以是基于数据库的文件系统,其中信息被表示为复杂类型实例。在参考标号1004处,确定与所表示的数据存储系统相关联的特性。特性可包括但不限于,与数据存储系统相关联的促使准确实现的限制、方针、规则、目标、蓝图和/或任何其它适当的元素。
在参考标号1006处,可通过利用至少一个过程来调用数据操纵。数据操纵可由API提供,其中用户可调用至少一个过程,其中过程可对应于至少一个数据操纵。可以理解,在调用数据操纵的同时维护和/或实施与数据存储系统相关联的特性。在参考标号1008处,可利用出错代码和/或可采用安全性。出错代码可例如在数据操纵侵害了数据存储系统的特性时生成和利用。可以理解,出错代码可经由API显示给用户,其中该代码可对应于将代码与文本消息相关的查找表。与数据操纵和/或API相关联的安全性可包括各种授权级别和/或登录和/或口令。换言之,每一数据操纵可与一安全级别相关联,其中仅一特定安全级别可实现这些过程和/或需要登录和口令。
在参考标号1010处,可实现与数据存储系统内的数据操纵有关的乐观并发性和/或死锁。乐观并发性假定另一进程在基本相似的时刻做出改变的可能性较低,因此它不取锁,直到改变已被提交给数据存储系统(例如,仓库)。通过采用这一技术,减少了锁定时间并提供了更好的数据库性能。在一个示例中,可随着对项的每一次修改保持一令牌以将改变与项相关联。换言之,乐观并发性可便于在两个并发的应用程序之间访问数据。另外,锁定可便于支持多个并发的调用者。例如,想像这样一种情形,其中有请求对一组公共资源的所有权的多个并发的调用者,它们以因为每一调用者都在等待其它调用者而使得没有一个请求能得到满足的方式来做出请求。在这一情况下,系统可阻断调用者(例如,将调用者锁住),其中离开这一情况的唯一方式是驱逐调用者之一。为避免这一情况,锁定可支持多个并发的调用者,使得复杂锁定逻辑可确保各个请求自动成功或失败。此外,可支持多个并发的调用者,使得复杂锁定逻辑可确保各个请求原子地成功或失败。
为了提供用于实现本发明的各方面的附加上下文,图11-12及以下讨论旨在提供对其中可实现本发明的各方面的合适的计算环境的简要概括描述。尽管上文中在运行在本地计算机和/或远程计算机上的计算机程序的计算机可执行指令的一般上下文中描述了本发明,但是本领域的技术人员将认识到,本发明也可结合其它程序模块来实现。一般而言,程序模块包括例程、程序、组件、数据结构等,它们执行特定任务和/或实现特定抽象数据类型。
此外,本领域的技术人员可以理解,本发明的方法可用其它计算机系统配置来实施,包括单处理器或多处理器计算机系统、小型机、大型计算机、以及个人计算机、手持式计算设备、基于微处理器的和/或可编程消费电子产品等,其每一个都可操作上与一个或多个相关联的设备通信。所示的本发明的各方面也可在分布式计算环境中实施,其中某些任务由通过通信网络链接的远程处理设备来执行。然而,本发明的某些(如果不是全部)方面也可在独立计算机上实施。在分布式计算环境中,程序模块可以位于本地和/或远程存储器存储设备中。
图11是本发明可与其交互的示例计算环境1100的示意框图。系统1100包括一个或多个客户机1110。客户机1110可以是硬件和/或软件(如,线程、进程、计算装置)。系统1100也包括一个或多个服务器1120。服务器1120也可以是硬件和/或软件(如,线程、进程、计算装置)。例如,服务器1120可容纳线程,以通过使用本发明执行变换。
客户机1110和服务器1120之间的一个可能的通信可以是适用于在两个或多个计算机进程之间传输的数据分组的形式。系统1100包括可用于便于在客户机1110和服务器1120之间通信的通信框架1140。客户机1110操作上连接至可用于储存对客户机1110本地的信息的一个或多个客户机数据存储1150。类似地,服务器1120操作上连接至可用于储存对服务器1140本地的信息的一个或多个服务器数据存储1130。
参考图12,用于实现本发明的各方面的示例性环境1200包括计算机1212。计算机1212包括处理单元1214、系统存储器1216和系统总线1218。系统总线1218将包括但不限于系统存储器1216的系统组件耦合至处理单元1214。处理单元1214可以是各种可用处理器的任一种。双微处理器和其它多处理器体系结构也可用作处理单元1214。
系统总线1218可以是若干种总线结构类型的任一种,包括存储器总线或存储器控制器、外围总线或外部总线、和/或使用各类可用总线体系结构的局部总线,这些体系结构包括但不限于,工业标准体系结构(ISA)、微通道体系结构(MSA)、扩展ISA(EISA)、智能驱动电子设备(IDE)、VESA局部总线(VLB)、外围部件互连(PCI),插件总线、通用串行总线(USB)、高级图形端口(AGP)、个人计算机存储卡国际协会总线(PCMCIA)、火线(IEEE 1394)以及小型计算机系统接口(SCSI)。
系统存储器1216包括易失性存储器1220和非易失性存储器1222。基本输入/输出系统(BIOS)包括如在启动时帮助在计算机1212内的元件之间传输信息的基本例程,它储存在非易失性存储器1222中。作为说明而非局限,非易失性存储器1222可包括只读存储器(ROM)、可编程ROM(PROM)、电可编程ROM(EPROM)、电可擦除可编程ROM(EEPROM)或闪存。易失性存储器1220包括担当外部高速缓存的随机存取存储器(RAM)。作为说明而非局限,RAM以许多形式可用,如静态RAM(SRAM)、动态RAM(DRAM)、同步DRAM(SDRAM)、双数据率SDRAM(DDR SDRAM)、增强型SDRAM(ESDRAM)、同步链路DRAM(SLDRAM)、Rambus直接RAM(RDRAM)、直接Rambus动态RAM(DRDRAM)以及Rambus动态RAM(RDRAM)。
计算机1212也包括可移动/不可移动、易失性/非易失性计算机存储介质。例如,图12示出了盘存储1224。盘存储1224包括但不限于,诸如磁盘驱动器、软盘驱动器、磁带驱动器、Jaz驱动器、Zip驱动器、LS-100驱动器、闪存卡或记忆棒等设备。另外,盘存储1224可单独包括存储介质或与其它存储介质组合,其它存储介质包括但不限于,诸如光盘ROM设备(CD-ROM)、CD可记录驱动器(CD-R驱动器)、CD可重写驱动器(CD-RW驱动器)或数字多功能盘ROM驱动器(DVD-ROM)等光盘驱动器。为便于盘存储设备1224连接到系统总线1218,通常使用可移动或不可移动接口,如接口1226。
可以理解,图12描述了担当用户和合适的操作环境1200中描述的基本计算机资源之间的中介的软件。这类软件包括操作系统1228。操作系统1228可储存在盘存储1224中,它用于控制并分配计算机系统1212的资源。系统应用程序1230利用操作系统1228通过储存在系统存储器1216或盘存储1224上的程序模块1232和程序数据1234对资源的管理。可以理解,本发明可用各种操作系统或操作系统的组合来实现。
用户通过输入设备1236向计算机1212输入命令或信息。输入设备1236包括但不限于,诸如鼠标、跟踪球、指示笔、触摸垫等定点设备、键盘、话筒、操纵杆、游戏垫、圆盘式卫星天线、扫描仪、TV调谐卡、数码相机、数码摄像机、web摄像头等等。这些和其它输入设备通过系统总线1218经由接口端口1238连接到处理单元1214。接口端口1238包括,例如,串行端口、并行端口、游戏端口以及通用串行总线(USB)。输出设备1240使用与输入设备1236相同类型端口中的某一些。由此,例如,USB端口可用于向计算机1212提供输入,并从计算机1212输出信息到输出设备1240。提供了输出适配器1242以说明存在一些输出设备1240,如监视器、扬声器和打印机,以及需要特殊适配器的其它输出设备1240。输出适配器1242包括,作为说明而非局限,提供输出设备1240和系统总线1218之间的连接手段的显卡和声卡。应当注意,其它设备和/或设备的系统提供了输入和输出能力,如远程计算机1244。
计算机1212可以使用到一个或多个远程计算机,如远程计算机1244的逻辑连接在网络化环境中操作。远程计算机1244可以是个人计算机、服务器、路由器、网络PC、工作站、基于微处理器的电器、对等设备或其它常见的网络节点等等,并通常包括相对于计算机1212所描述的许多或所有元件。为简明起见,仅对远程计算机1244示出了存储器存储设备1246。远程计算机1244通过网络接口1248逻辑上连接至计算机1212,然后通过通信连接1250物理地连接。网络接口1248包含诸如局域网(LAN)和广域网(WAN)等有线和/或无线通信网络。LAN技术包括光纤分布式数据接口(FDDI)、铜缆分布式数据接口(CDDI)、以太网、令牌环等等。WAN技术包括但不限于,点对点链路、诸如综合业务数字网(ISDN)及其变型等电路交换网络、分组交换网络以及数字用户线(DSL)。
通信连接1250指用于将网络接口1248连接到总线1218的硬件/软件。尽管为说明清晰起见,示出通信连接1250在计算机1212内,然而它也可以对计算机1212是外部的。仅出于示例性目的,连接到网络接口1248所必需的硬件/软件包括内部和外部技术,如包括常规电话级调制解调器、线缆调制解调器和DSL调制解调器的调制解调器、ISDN适配器和以太网卡。
以上所描述的包括本发明的示例。当然,不可能为了描述本发明而描述组件或方法的每一可想到的组合,但是本领域的普通技术人员可以认识到,本发明的许多其它组合和置换都是可能的。因此,本发明旨在包含落入所附权利要求书的精神和范围内的所有这些变更、修改和变化。
特别地,对于由上述组件、设备、电路、系统等执行的各种功能,除非另外指明,否则用于描述这些组件的术语(包括对“装置”的引用)旨在对应于执行所描述的执行此处所示的本发明的示例性方面中的功能的组件的指定功能(例如,功能上等效)的任何组件,即使这些组件在结构上不等效于所公开的结构。在这一点上,也可认识到本发明包括用于执行本发明的各种方法的动作和/或事件的系统以及具有用于执行这些动作和/或事件的计算机可执行指令的计算机可读介质。
另外,尽管可相对于若干实现中的仅一个公开本发明的一个特定特征,但是这一特征可以如对任何给定或特定应用所需且有利地与其它实现的一个或多个其它特征相组合。此外,就在说明书或权利要求书中使用术语“包括”和“含有”及其变型而言,这些术语旨在以类似于术语“包含”相似的方式为包含性的。